Aufrufen einer Funktion eines Moduls unter Verwendung seines Namens (einer Zeichenfolge)

  • Was ist der beste Weg, um eine Funktion mit einem String mit dem Namen der Funktion in einem Python-Programm aufzurufen? Angenommen, ich habe ein Modul foo und eine Zeichenfolge, deren Inhalt "bar" ist. Was ist der beste Weg, um foo.bar() aufzurufen?

    Ich muss den Rückgabewert der Funktion abrufen, weshalb ich nicht einfach eval verwende. Ich habe herausgefunden, wie das geht, indem ich mit eval eine temporäre Funktion definiere, die das Ergebnis dieses Funktionsaufrufs zurückgibt, aber ich hoffe, dass es einen eleganteren Weg gibt, dies zu tun.

    31 December 2017
    Claus WilkeDan
10 answers
  • Modul foo mit Methode bar übernehmen:

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

    Soweit Zeilen 2 und 3 können folgendermaßen komprimiert werden:

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

    , wenn dies für Ihren Anwendungsfall sinnvoller ist. Sie können getattr auf diese Weise für an Klasseninstanzen gebundene Methoden, Methoden auf Modulebene, Klassenmethoden verwenden. Die Liste wird fortgesetzt.

    22 February 2017
    Ben HoytA. Coady
  •  locals()["myfunction"]()
     

    oder

     globals()["myfunction"]()
     

    Einheimische gibt ein Wörterbuch mit einer aktuellen lokalen Symboltabelle zurück. globals gibt ein Wörterbuch mit globaler Symboltabelle zurück.

    07 May 2009
    sastanin
  • Patricks Lösung ist wahrscheinlich die sauberste. Wenn Sie das Modul auch dynamisch abholen müssen, können Sie es wie folgt importieren:

     module = __import__('foo')
    func = getattr(module, 'bar')
    func()
     
    22 February 2017
    Ben HoytA. Coady
  • Nur ein einfacher Beitrag. Wenn sich die Klasse, die wir instanziieren müssen, in derselben Datei befindet, können wir Folgendes verwenden:

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

    Zum Beispiel:

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

    Und falls keine Klasse:

     def sampleFunc(arg):
        print('you called sampleFunc({})'.format(arg))
    
    globals()['sampleFunc']('sample arg')
     
    23 September 2014
    tbc0
  • Bei einer gegebenen Zeichenfolge mit einem vollständigen Python-Pfad zu einer Funktion habe ich das Ergebnis dieser Funktion abgerufen:

     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()
     
    16 October 2013
    ferrouswheel
  • Die Antwort (hoffentlich) niemand wollte

    Gleiches Verhalten

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

    Warum nicht Auto-Import hinzufügen?

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

    Falls es so ist Zusätzliche Wörterbücher, die wir prüfen möchten

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

    Wir müssen tiefer gehen

     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")()
     
    09 April 2014
    00500005
  • Die beste Antwort gemäß den Häufig gestellte Fragen zur Python-Programmierung wären:

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

    Der Hauptvorteil dieser Technik besteht darin, dass die Zeichenfolgen nicht mit den Namen der Funktionen übereinstimmen müssen. Dies ist auch die Hauptmethode, mit der ein Fallkonstrukt

    emuliert wird
    24 October 2016
  • Wenn Sie den Namen der Funktion (oder der Klasse) und den Namen der App als String übergeben möchten, können Sie Folgendes tun:

     myFnName  = "MyFn"
    myAppName = "MyApp"
    app = sys.modules[myAppName]
    fn  = getattr(app,myFnName)
     
    14 February 2012
    trubliphone
  • Nichts von dem, was vorgeschlagen wurde, hat mir geholfen. Ich habe dies jedoch entdeckt.

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

    Ich verwende Python 2.66

    Ich hoffe, das hilft

    28 December 2012
    Natdrip
  • Versuchen Sie dies. Während dies noch eval verwendet, wird nur verwendet, um die Funktion aus dem aktuellen Kontext aufzurufen. Dann haben Sie die eigentliche Funktion, die Sie nach Belieben verwenden können.

    Der Hauptvorteil für mich ist, dass Sie evtl. Fehler in Verbindung mit der eval-Funktion erhalten, sobald die Funktion aufgerufen wird . Dann erhalten Sie beim Aufruf nur die funktionsbezogenen Fehler.

     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)
     
    08 December 2016
    tvt173