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

Translate

Was ist der beste Weg, um eine Funktion mit einem String mit dem Namen der Funktion in einem Python-Programm aufzurufen? Nehmen wir zum Beispiel an, ich habe ein Modulfoound ich habe eine Zeichenfolge, deren Inhalt ist"bar". Was ist der beste Weg, um anzurufenfoo.bar()?

Ich muss den Rückgabewert der Funktion erhalten, weshalb ich nicht nur verwendeeval. Ich fand heraus, wie es gehtevalum eine temporäre Funktion zu definieren, die das Ergebnis dieses Funktionsaufrufs zurückgibt, aber ich hoffe, dass es einen eleganteren Weg gibt, dies zu tun.

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Modul übernehmenfoomit Methodebar:

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

Soweit das geht, können die Zeilen 2 und 3 komprimiert werden auf:

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

wenn das für Ihren Anwendungsfall sinnvoller ist. Sie können verwendengetattrAuf diese Weise wird die Liste für Klasseninstanz-gebundene Methoden, Methoden auf Modulebene, Klassenmethoden ... fortgesetzt.

Quelle
Translate
locals()["myfunction"]()

or

globals()["myfunction"]()

EinheimischeGibt ein Wörterbuch mit einer aktuellen lokalen Symboltabelle zurück.GlobaleGibt ein Wörterbuch mit globaler Symboltabelle zurück.

Quelle
HS.
Translate

Patricks Lösung ist wahrscheinlich die sauberste. Wenn Sie das Modul auch dynamisch aufnehmen müssen, können Sie es wie folgt importieren:

module = __import__('foo')
func = getattr(module, 'bar')
func()
Quelle
Translate

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 wenn nicht eine Klasse:

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

globals()['sampleFunc']('sample arg')
Quelle
Translate

Bei einer gegebenen Zeichenfolge mit einem vollständigen Python-Pfad zu einer Funktion habe ich das Ergebnis dieser Funktion auf folgende Weise erhalten:

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()
Quelle
Cornelius Lee
Translate

Die beste Antwort nach demHäufig gestellte Fragen zur Python-Programmierungwäre:

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 primäre Technik, die zum Emulieren eines Fallkonstrukts verwendet wird

Quelle
Translate

Die Antwort (ich hoffe) wollte niemand jemals

Eval wie Verhalten

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

Warum nicht den automatischen Import hinzufügen?

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

Falls wir zusätzliche Wörterbücher haben, möchten wir diese überprüfen

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")()
Quelle
Translate

Wenn Sie den Funktions- (oder Klassen-) Namen und den App-Namen als Zeichenfolge übergeben müssen, können Sie Folgendes tun:

myFnName  = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn  = getattr(app,myFnName)
Quelle
Translate

Versuche dies. Während dies immer noch eval verwendet, wird es nur dazu verwendetRufen Sie die Funktion aus dem aktuellen Kontext auf. Dann haben Sie die eigentliche Funktion, die Sie nach Belieben verwenden können.

Der Hauptvorteil für mich besteht darin, dass Sie beim Aufrufen der Funktion alle evalbezogenen Fehler erhalten. Dann wirst du bekommennurdie funktionsbezogenen Fehler beim Aufruf.

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)
Quelle
Translate

Nichts von dem, was vorgeschlagen wurde, half mir. Ich habe das allerdings entdeckt.

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

Ich benutze Python 2.66

Hoffe das hilft

Quelle
Translate

Wie diese FrageDynamisches Aufrufen von Methoden innerhalb einer Klasse mithilfe der Zuweisung von Methodennamen zu einer Variablen [Duplikat]Als Duplikat wie dieses markiert, poste ich hier eine verwandte Antwort:

Das Szenario ist, dass eine Methode in einer Klasse eine andere Methode für dieselbe Klasse dynamisch aufrufen möchte. Ich habe dem ursprünglichen Beispiel einige Details hinzugefügt, die ein breiteres Szenario und Klarheit bieten:

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

Ausgabe (Python 3.7.x)

Funktion1: 12

Funktion2: 12

Quelle
Translate

Dies ist eine einfache Antwort, mit der Sie beispielsweise den Bildschirm löschen können. Im Folgenden finden Sie zwei Beispiele mit eval und exec, die nach dem Bereinigen oben 0 ausgeben (wenn Sie Windows verwenden, ändern Sie dieseclearzucls, Linux- und Mac-Benutzer lassen es wie es ist) oder führen es einfach aus.

eval("os.system(\"clear\")")
exec("os.system(\"clear\")")
Quelle