Modulio funkcijos skambinimas naudojant jo pavadinimą (eilutę)

Koks yra geriausias būdas paskambinti funkciją tam tikroje eilutėje su Python programos funkcijos pavadinimu. Pavyzdžiui, tarkime, kad turiu modulį foo , ir turiu eilutę su "bar" turiniu. Koks yra geriausias būdas skambinti foo.bar() ?

Turiu gauti funkcijos grąžos vertę, todėl aš ne tik naudoju eval . Aš supratau, kaip tai padaryti naudojant eval kad nustatytumėte laikiną funkciją, kuri grąžina skambinimo į šią funkciją rezultatą, bet tikiuosi, kad tai yra elegantiškesnis būdas.

1323
06 авг. ricree 06 rug . 2008-08-06 06:36 '08 6:36 am. 2008-08-06 06:36
@ 10 atsakymų

Darant prielaidą, kad foo modulis naudojamas bar metodu:

 import foo method_to_call = getattr(foo, 'bar') result = method_to_call() 

Kiek įmanoma, 2 ir 3 eilutės gali būti suspaustos į:

 result = getattr(foo, 'bar')() 

jei tai naudinga jūsų naudojimo atvejui. Tokiu būdu getattr galite naudoti, pavyzdžiui, klasių apribojimų metodus, modulio lygio metodus, klasės metodus ... sąrašas getattr .

1596 m
06 авг. Patrick Johnmeyer atsakymas rugpjūčio 6 d 2008-08-06 06:57 '08 at 6:57 2008-08-06 06:57
 locals()["myfunction"]() 

arba

border=0
 globals()["myfunction"]() 

vietiniai gyventojai grąžina žodyną su dabartine vietos simbolių lentele. „globals“ grąžina žodyną su pasauline simbolių lentele.

434
07 мая '09 в 15:45 2009-05-07 15:45 atsakymas pateikiamas sastanin gegužės 07'09 , 15:45 2009-05-07 15:45

Patricko sprendimas tikriausiai yra švariausias. Jei reikia dinamiškai padidinti modulį, galite jį importuoti kaip:

 module = __import__('foo') func = getattr(module, 'bar') func() 
269
Atsakymas yra HS. Rugpjūtis 07 2008-08-07 14:35 '08 at 14:35 2008-08-07 14:35

Tiesiog paprastas įnašas. Jei klasė, kuri mums reikalinga egzemplioriui, yra toje pačioje rinkmenoje, galime naudoti kažką panašaus:

 # Get class from globals and create an instance m = globals()['our_class']() # Get the function (from the instance) that we need to call func = getattr(m, 'function_name') # Call it func() 

Pavyzdžiui:

 class A: def __init__(self): pass def sampleFunc(self, arg): print('you called sampleFunc({})'.format(arg)) m = globals()['A']() func = getattr(m, 'sampleFunc') func('sample arg') # Sample, all on one line getattr(globals()['A'](), 'sampleFunc')('sample arg') 

Ir jei ne klasė:

 def sampleFunc(arg): print('you called sampleFunc({})'.format(arg)) globals()['sampleFunc']('sample arg') 
90
19 авг. Sourcegeek atsakymas rugpjūčio 19 d 2012-08-19 12:40 '12 12:40 2012-08-19 12:40

Atsižvelgiant į eilutę su visu funkcijų pythono keliu, aš pradėjau gauti nurodytos funkcijos rezultatą:

 import importlib function_string = 'mypackage.mymodule.myfunc' mod_name, func_name = function_string.rsplit('.',1) mod = importlib.import_module(mod_name) func = getattr(mod, func_name) result = func() 
73
16 окт. atsakymą pateikia geležies ratas 16 okt. 2013-10-16 03:24 '13, 3:24, 2013-10-16 03:24

Geriausias atsakymas pagal Python programavimo DUK:

 functions = {'myfoo': foo.bar} mystring = 'myfoo' if mystring in functions: functions[mystring]() 

Pagrindinis šio metodo privalumas yra tas, kad stygos neturėtų sutapti su funkcijų pavadinimais. Tai taip pat yra pagrindinis metodas, naudojamas imituojant bylų konstrukciją.

37
24 окт. vartotojo3946687 atsakymas spalio 24 d 2016-10-24 16:20 '16, 16:20 pm 2016-10-24 16:20

Atsakymas yra (tikiuosi) niekas niekada nenorėjo

Pagrindinis elgesys

 getattr(locals().get("foo") or globals().get("foo"), "bar")() 

Kodėl nepridėsite automatinio importo

 getattr( locals().get("foo") or globals().get("foo") or __import__("foo"), "bar")() 

Jei turime papildomų žodynų, norime patikrinti

 getattr(next((x for x in (f("foo") for f in [locals().get, globals().get, self.__dict__.get, __import__]) if x)), "bar")() 

Turime giliau eiti

 getattr(next((x for x in (f("foo") for f in ([locals().get, globals().get, self.__dict__.get] + [d.get for d in (list(dd.values()) for dd in [locals(),globals(),self.__dict__] if isinstance(dd,dict)) if isinstance(d,dict)] + [__import__])) if x)), "bar")() 
35
09 апр. atsakymas pateiktas 00500005 09 balandis. 2014-04-09 13:17 '14 at 13:17 2014-04-09 13:17

Ką tai kainuoja, jei reikia perduoti funkcijos (ar klasės) pavadinimą ir programos pavadinimą kaip eilutę, galite tai padaryti:

 myFnName = "MyFn" myAppName = "MyApp" app = sys.modules[myAppName] fn = getattr(app,myFnName) 
21
14 февр. atsakymą pateikė trubliphone 14 vasaris. 2012-02-14 08:55 '12 at 8:55 2012-02-14 08:55

Išbandykite. Nors jis vis dar naudoja eval, jis naudoja tik funkcijai skambinti iš dabartinio konteksto. Tada jūs turite tikrą funkciją, kaip norite.

Pagrindinis privalumas man yra tai, kad funkcijų skambučio metu atsiranda bet kokių klaidų, susijusių su evalu. Po to gausite tik su funkcija susijusias klaidas.

 def say_hello(name): print 'Hello {}!'.format(name) # get the function by name method_name = 'say_hello' method = eval(method_name) # call it like a regular function later args = ['friend'] kwargs = {} method(*args, **kwargs) 
16
07 дек. atsakymas yra pateiktas tvt173 07 dec. 2016-12-07 21:29 '16 at 21:29 2016-12-07 21:29

nė vienas iš siūlomų nebuvo man padėjęs. Radau jį.

 <object>.__getattribute__(<string name>)(<params>) 

Aš naudoju 2.66 python

Tikiuosi, kad tai padės

15
28 дек. Atsakymas duotas „ Natdrip“ 28 d. 2012-12-28 19:56 '12 19:56 val. 2012-12-28 19:56

Kiti klausimai apie etiketes arba Užduoti klausimą