Volání funkce modulu pomocí názvu (řetězec)

hlasů
1k

Jaký je nejlepší způsob, jak jít o volání funkce daný řetězec s názvem Funkce v programu Python. Například, řekněme, že mám modul foo, a já mám řetězec, jehož obsah je bar. Jaký je nejlepší způsob, jak jít o volání foo.bar()?

Musím se dostat návratovou hodnotu funkce, což je důvod, proč nemám jen používat eval. Přišel jsem na to, jak to udělat pomocí evaldefinovat funkci temp, která vrací výsledek tohoto volání funkce, ale já doufám, že tam je více elegantní způsob, jak toho dosáhnout.

Položena 06/08/2008 v 04:36
zdroj uživatelem
V jiných jazycích...                            


12 odpovědí

hlasů
1k

Za předpokladu, že modul foos metodou bar:

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

Pokud je to, že jde, linie 2 a 3 mohou být komprimovány do:

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

jestli to dává větší smysl pro váš případ použití. Můžete použít getattrtímto způsobem na instance třídy vázaných metod, metod na úrovni modulu, metod třídy ... seznam by mohl pokračovat dál.

Odpovězeno 06/08/2008 v 04:57
zdroj uživatelem

hlasů
387
locals()["myfunction"]()

nebo

globals()["myfunction"]()

Místní vrací slovník s aktuální místní tabulky symbolů. globals vrací slovník s globální symbol tabulky.

Odpovězeno 07/05/2009 v 13:45
zdroj uživatelem

hlasů
229

Patrika řešení je pravděpodobně nejčistší. Pokud potřebujete dynamicky vyzvednout modul také můžete importovat to líbí:

module = __import__('foo')
func = getattr(module, 'bar')
func()
Odpovězeno 07/08/2008 v 12:35
zdroj uživatelem

hlasů
77

Jen jednoduchý příspěvek. V případě, že třída, která musíme případě je v jednom souboru, můžeme použít něco takového:

# 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()

Například:

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')

A není-li třídy:

def sampleFunc(arg):
    print('you called sampleFunc({})'.format(arg))

globals()['sampleFunc']('sample arg')
Odpovězeno 19/08/2012 v 10:40
zdroj uživatelem

hlasů
64

Vzhledem k tomu, řetězec, s kompletním python cestě k funkci, je to, jak jsem se o to jak výsledek zmíněné funkce:

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()
Odpovězeno 16/10/2013 v 01:24
zdroj uživatelem

hlasů
30

Odpověď (doufám), nikdo nechtěl

Eval jako chování

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

Proč ne přidat auto-import

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

V případě, že máme další slovníky chceme kontrolovat

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

Musíme jít hlouběji,

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")()
Odpovězeno 09/04/2014 v 11:17
zdroj uživatelem

hlasů
26

Nejlepší odpověď podle programového FAQ Python bude vypadat následovně:

functions = {'myfoo': foo.bar}

mystring = 'myfoo'
if mystring in functions:
    functions[mystring]()

Hlavní výhodou této metody je, že struny nemusí shodovat s názvy funkcí. To je také hlavním technika používaná k emulaci případ konstrukt

Odpovězeno 24/10/2016 v 13:20
zdroj uživatelem

hlasů
18

Za to, co stojí za to, pokud jste potřebovali předat funkci (nebo třídy) jméno a jméno aplikace jako řetězec, pak byste mohli udělat toto:

myFnName  = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn  = getattr(app,myFnName)
Odpovězeno 14/02/2012 v 06:55
zdroj uživatelem

hlasů
15

Zkuste to. I když to stále používá eval, využívá ji pouze zavolat funkci z aktuálního kontextu . Potom máte skutečnou funkci používat, jak budete chtít.

Hlavním přínosem pro mě z toho je, že budete mít nějaké chyby eval souvisejících v místě přivolání funkci. Pak dostanete pouze chyby funkce související při volání.

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)
Odpovězeno 07/12/2016 v 18:29
zdroj uživatelem

hlasů
13

nic z toho, co bylo navrženo mi pomohl. Udělal jsem objevit tento ačkoli.

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

Já používám Python 2,66

Snad to pomůže

Odpovězeno 28/12/2012 v 17:56
zdroj uživatelem

hlasů
0

To je jednoduchá odpověď, to vám umožní vyčistit obrazovku například. K dispozici jsou dva příklady níže s eval a exec, který bude vytištěno 0 v horní části po vyčištění (pokud používáte systém Windows, změní clearse cls, Linux a Mac uživatelé odejít jako je například), nebo jen spustit jej, resp.

eval("os.system(\"clear\")")
exec("os.system(\"clear\")")
Odpovězeno 28/08/2019 v 19:46
zdroj uživatelem

hlasů
0

Protože tato otázka Jak dynamicky volání metody v rámci třídy pomocí přiřazení metoda-name na variabilní [duplikátu] označen jako duplikát, jako je tento, jsem vysílání související odpověď zde:

Scénář je metoda ve třídě chcete volat jinou metodu na stejné třídy dynamicky, jsem přidal pár detailů k původnímu příkladu, který nabízí nějaké širší scénář a jasnost:

class MyClass:
def __init__(self, i):
    self.i = i

def get(self):
    func = getattr(MyClass, 'function{}'.format(self.i))
    func(self, 12)   # This one will work
    # self.func(12)    # But this does NOT work.


def function1(self, p1):
    print('function1: {}'.format(p1))
    # do other stuff

def function2(self, p1):
    print('function2: {}'.format(p1))
    # do other stuff


if __name__ == "__main__":
    class1 = MyClass(1)
    class1.get()
    class2 = MyClass(2)
    class2.get()

Výstup (Python 3.7.x)

Function1: 12

function2: 12

Odpovězeno 26/03/2019 v 18:15
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more