2009-04-01 12 views
2

Was ist der beste Weg, eine Methode und einen Methodenparameter an eine andere Methode zu übergeben?Was ist der beste Weg, eine Methode (mit Parametern) an eine andere Methode in Python zu übergeben

Gibt es eine bessere Möglichkeit, Folgendes zu tun?

def method1(name) 
    return 'Hello ' + name 

def method2(methodToCall, methodToCallParams, question): 
    greetings = methodToCall(methodToCallParams) 
    return greetings + ', ' + question 

method2(method1, 'Sam', 'How are you?') 
+0

Was versuchen Sie damit? Warum eine Methode und Parameter übergeben? Warum nicht einfach die Methode aufrufen und damit fertig sein? –

+0

Dies ist ein schlechtes Beispiel, aber meine Methode2 ist eigentlich eine Versuchsmethode, es wird methode1 x Menge an Zeit aufrufen und schlägt fehl .. Ich versuche es als Hilfsmethode zu machen, so kann ich eine Reihe von verschiedenen Methoden weitergeben, um – Dan

Antwort

3

Man könnte es auf diese Weise tun:

def method1(name): 
    def wrapper(): 
     return 'Hello ' + name 
    return wrapper 

def method2(method, question): 
    output = method() 
    return output + ', ' + question 

method2(method1(name = 'Sam'), 'How are you?') 

Sie können natürlich einige Variablen in der Methode übergeben() aufrufen zu:

def method1(name): 
    def wrapper(greeting): 
     return greeting + name 
    return wrapper 

def method2(method, question): 
    output = method(greeting = 'Hello ') 
    return output + ', ' + question 

method2(method1(name = 'Sam'), 'How are you?') 
+0

Great .. es funktioniert perfekt – Dan

+0

functools.partial ist eine sauberere Möglichkeit, dies zu tun. –

0

Sie denken an currying, wo Sie eine Funktion und Argumente zusammen binden später aufgerufen werden. Gewöhnlich wird currying verwendet, so dass Sie zusätzliche Argumente hinzufügen können, wenn die Funktion tatsächlich aufgerufen wird.

Anstatt das Rad neu zu schreiben, hier ist ein Link zu einem Beispiel: http://code.activestate.com/recipes/52549/.

Wenn Sie jedoch in der Frage wirklich so einfach vorgegangen sind, können Sie eine Liste von Argumenten als Positionsparameter oder eine Liste von Kwargen als benannte Parameter an eine andere Funktion übergeben.

def method1(name): 
    return 'Hello %s' % name 

args = ['Joe'] 
method1(*args) 

def method1a(name=None, salutation=None): 
    return 'Hello %s %s' % (name, salutation) 

kwargs = {'name':'Joe', 'salutation':'Mr'} 
method1a(**kwargs) 
+0

zu versuchen Dies beantwortet nicht wirklich die Frage: Sie zeigen nur, wie man Argumente packt und entpackt, nicht wie man sie an eine Funktion bindet und sie als eine Einheit weitergibt. – jkp

11

Wenn Sie den Aufruf nach oben in einen Treffer verpacken wollen, können Sie das functools Modul verwenden:

from functools import partial 

def some_function(param_one, param_two): 
    print "Param One: %s" % param_one 
    print "Param Two: %s" % param_two 

def calling_function(target): 
    target() 

calling_function(partial(some_function, "foo", "bar")) 

Sie zu tweakier Dinge mit functools.partial tun können, wie nur einige Parameter verbindlich Sie erhalten eine Funktion mit einer neuen Signatur. Es ist in vielen Fällen Overkill, es zu benutzen, aber es hat seinen Platz.

+0

Wow, das ist genau das, was ich suche, außer dass ich auf Python 2.4 bin und das erfordert 2.6 :(Wenn ich keine bessere Antwort bekomme, werde ich Ihre Antwort annehmen – Dan

+0

Ich habe gerade eine Antwort geschrieben, die zeigt, wie Erstellen Sie eine ungefähr äquivalente Funktion zu funktools.partial für die Verwendung mit Python-Versionen vor 2.5, in Verbindung mit @ JKP Antwort sollte es den Job erledigt – Jay

1

Eine weitere Option, wenn Sie auf einem Python arbeiten Version vor 2.5 ist eine Lambda als Verschluss zu verwenden:

def some_func(bar): 
    print bar 

def call_other(other): 
    other() 

call_other(lambda param="foo": some_func(param)) 

HTH

+0

Ich brauche den Rückgabewert .. aber ich upu, weil es immer noch eine nette Antwort ist – Dan

2

Sie können functools.partial verwendet, dies zu tun, als jkp pointed out

ist jedoch functools neu in Python 2.5, so dass dies ich den folgenden Code in der Vergangenheit zu handhaben verwendet (dieser Code in der Python-Dokumentation für functools.partial ist , eigentlich).

# functools is Python 2.5 only, so we create a different partialfn if we are 
# running a version without functools available 
try: 
    import functools 
    partialfn = functools.partial 
except ImportError: 
    def partialfn(func, *args, **keywords): 
     def newfunc(*fargs, **fkeywords): 
      newkeywords = keywords.copy() 
      newkeywords.update(fkeywords) 
      return func(*(args + fargs), **newkeywords) 
     newfunc.func = func 
     newfunc.args = args 
     newfunc.keywords = keywords 
     return newfunc 
Verwandte Themen