Aufruf einer Funktion eines Moduls durch seinen Namen (String)

stimmen
1k

Was ist der beste Weg , um eine Zeichenfolge , die eine Funktion über Aufruf mit der Namen der Funktion in einem Python - Programm gegeben zu gehen. Zum Beispiel, sagen wir mal , dass ich ein Modul haben foo, und ich habe eine Zeichenfolge , deren Inhalt bar. Was ist der beste Weg , um Aufruf zu gehen foo.bar()?

Ich brauche den Rückgabewert der Funktion zu erhalten, weshalb ich ist nicht nur zu verwenden eval. Ich fand heraus , wie es zu tun , indem Sie evaleine temporäre Funktion zu definieren , die das Ergebnis dieser Funktion Aufruf gibt, aber ich hoffe , dass es eine elegantere Art und Weise, dies zu tun.

Veröffentlicht am 06/08/2008 um 04:36
quelle vom benutzer
In anderen Sprachen...                            


12 antworten

stimmen
1k

Unter der Annahme , Modul foomit Verfahren bar:

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

Wie weit das geht, Linien 2 und 3 können komprimiert werden:

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

wenn das macht mehr Sinn für Ihren Anwendungsfall. Sie können mit getattrauf Klasseninstanz gebunden Methoden auf Modulebene Methoden, Klassenmethoden auf diese Weise ... die Liste geht weiter.

Beantwortet am 06/08/2008 um 04:57
quelle vom benutzer

stimmen
387
locals()["myfunction"]()

oder

globals()["myfunction"]()

Einheimische gibt einen Wörterbuch mit einer aktuellen lokalen Symboltabelle. Globals gibt einen Wörterbuch mit globaler Symboltabelle.

Beantwortet am 07/05/2009 um 13:45
quelle vom benutzer

stimmen
229

Patrick Lösung ist wahrscheinlich die sauberste. Wenn Sie dynamisch müssen auch das Modul abholen, können Sie importieren möchten:

module = __import__('foo')
func = getattr(module, 'bar')
func()
Beantwortet am 07/08/2008 um 12:35
quelle vom benutzer

stimmen
77

Nur ein einfacher Beitrag. Wenn die Klasse, die wir beispielsweise müssen in der gleichen Datei ist, können wir so etwas wie folgt 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()

Beispielsweise:

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')
Beantwortet am 19/08/2012 um 10:40
quelle vom benutzer

stimmen
64

Bei einer Schnur, mit einem kompletten Python Pfad zu einer Funktion, das ist, wie ich ging über das Ergebnis der Funktion bekommen:

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()
Beantwortet am 16/10/2013 um 01:24
quelle vom benutzer

stimmen
30

Die Antwort (hoffentlich) niemand wollte

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

Sollten wir zusätzliche Wörterbücher wir möchten ü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")()
Beantwortet am 09/04/2014 um 11:17
quelle vom benutzer

stimmen
26

Die beste Antwort nach der Python - Programmierung FAQ wäre:

functions = {'myfoo': foo.bar}

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

Der primäre Vorteil dieser Technik besteht darin, dass die Saiten nicht brauchen, um die Namen der Funktionen anzupassen. Dies ist auch die Haupttechnik verwendet, um ein Fall-Konstrukt zu emulieren

Beantwortet am 24/10/2016 um 13:20
quelle vom benutzer

stimmen
18

Für das, was es wert ist, wenn man benötigt, um die Funktion (oder Klasse) Name und App-Namen als String übergeben, dann können Sie dies tun:

myFnName  = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn  = getattr(app,myFnName)
Beantwortet am 14/02/2012 um 06:55
quelle vom benutzer

stimmen
15

Versuche dies. Während dies noch eval verwendet, verwendet er es nur die Funktion aus dem aktuellen Kontext zu rufen . Dann haben Sie die eigentliche Funktion zu verwenden , wie Sie es wünschen.

Der größte Vorteil für mich ist , dass Sie die Funktion der Einberufung keine eval bezogene Fehler an dem Punkt bekommen. Dann erhalten Sie nur die funktionsbezogene Fehler , wenn Sie anrufen.

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)
Beantwortet am 07/12/2016 um 18:29
quelle vom benutzer

stimmen
13

keiner von dem, was mir vorgeschlagen geholfen. Ich tat dies aber entdecken.

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

Ich verwende Python 2,66

Hoffe das hilft

Beantwortet am 28/12/2012 um 17:56
quelle vom benutzer

stimmen
0

Dies ist eine einfache Antwort, dies ermöglicht es Ihnen , den Bildschirm beispielsweise zu löschen. Es gibt zwei Beispiele unten, mit eval und exec, die nach der Reinigung 0 an der Spitze gedruckt werden (wenn Sie Windows verwenden, ändern clearzu cls, Linux und Mac - Anwender verlassen , wie zum Beispiel) oder einfach auszuführen sind.

eval("os.system(\"clear\")")
exec("os.system(\"clear\")")
Beantwortet am 28/08/2019 um 19:46
quelle vom benutzer

stimmen
0

Da diese Frage Wie dynamisch innerhalb einer Klasse Methoden aufrufen mit Methodenname Zuweisung zu einer Variablen [Duplikat] als Duplikat wie diese markiert, ich bin Entsendung eine ähnliche Antwort hier:

Das Szenario ist, eine Methode in einer Klasse dynamisch eine andere Methode auf der gleichen Klasse nennen wollen, ich habe einige Details zu den ursprünglichen Beispiel gegeben, die etwas breitere Szenario und Klarheit bietet:

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

Ausgang (Python 3.7.x)

function1: 12

function2: 12

Beantwortet am 26/03/2019 um 18:15
quelle vom benutzer

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