Est-il possible de passer une méthode en tant que paramètre à une méthode?
self.method2(self.method1)
def method1(self):
return 'hello world'
def method2(self, methodToRun):
result = methodToRun.call()
return result
Oui, utilisez simplement le nom de la méthode, comme vous l'avez écrit. Les méthodes/fonctions sont des objets en Python, comme n'importe quoi d'autre, et vous pouvez les transmettre à votre façon de traiter les variables. En fait, vous pouvez considérer une méthode (ou une fonction) comme une variable dont la valeur est l'objet de code appelable réel.
Pour votre information, il n’ya pas de méthode call
- je crois qu’elle s’appelle __call__
, mais vous n'êtes pas obligé de l'invoquer explicitement:
def method1():
return 'hello world'
def method2(methodToRun):
result = methodToRun()
return result
method2(method1)
Si tu voulais method1
être appelé avec des arguments, alors les choses se compliquent un peu. method2
_ doit être écrit avec un peu d’information sur la manière de passer des arguments à method1
, et il doit obtenir des valeurs pour ces arguments quelque part. Par exemple, si method1
est supposé prendre un argument:
def method1(spam):
return 'hello ' + str(spam)
alors vous pourriez écrire method2
pour l'appeler avec un argument qui est transmis:
def method2(methodToRun, spam_value):
return methodToRun(spam_value)
ou avec un argument qu'il se calcule lui-même:
def method2(methodToRun):
spam_value = compute_some_value()
return methodToRun(spam_value)
Vous pouvez élargir cela à d’autres combinaisons de valeurs transmises et calculées, comme
def method1(spam, ham):
return 'hello ' + str(spam) + ' and ' + str(ham)
def method2(methodToRun, ham_value):
spam_value = compute_some_value()
return methodToRun(spam_value, ham_value)
ou même avec des arguments de mots clés
def method2(methodToRun, ham_value):
spam_value = compute_some_value()
return methodToRun(spam_value, ham=ham_value)
Si vous ne savez pas, en écrivant method2
, quels arguments methodToRun
va prendre, vous pouvez également utiliser le décompactage d'argument pour l'appeler de manière générique:
def method1(spam, ham):
return 'hello ' + str(spam) + ' and ' + str(ham)
def method2(methodToRun, positional_arguments, keyword_arguments):
return methodToRun(*positional_arguments, **keyword_arguments)
method2(method1, ['spam'], {'ham': 'ham'})
Dans ce cas positional_arguments
doit être une liste ou un tuple ou similaire, et keyword_arguments
est un dict ou similaire. Dans method2
vous pouvez modifier positional_arguments
et keyword_arguments
(par exemple, pour ajouter ou supprimer certains arguments ou modifier les valeurs) avant d'appeler method1
.
Oui c'est possible. Il suffit d'appeler ça:
class Foo(object):
def method1(self):
pass
def method2(self, method):
return method()
foo = Foo()
foo.method2(foo.method1)
Voici votre exemple réécrit pour montrer un exemple de travail autonome:
class Test:
def method1(self):
return 'hello world'
def method2(self, methodToRun):
result = methodToRun()
return result
def method3(self):
return self.method2(self.method1)
test = Test()
print test.method3()
Oui; les fonctions (et méthodes) sont des objets de première classe en Python. Les oeuvres suivantes:
def foo(f):
print "Running parameter f()."
f()
def bar():
print "In bar()."
foo(bar)
Les sorties:
Running parameter f().
In bar().
Il est facile de répondre à ces questions en utilisant l’interprète Python ou, pour plus de fonctionnalités, le shell IPython .
Si vous voulez passer une méthode d'une classe en tant qu'argument mais que vous n'avez pas encore l'objet sur lequel vous allez l'appeler, vous pouvez simplement passer l'objet une fois que vous l'avez comme premier argument (c'est-à-dire le "self" argument).
class FooBar:
def __init__(self, prefix):
self.prefix = prefix
def foo(self, name):
print "%s %s" % (self.prefix, name)
def bar(some_method):
foobar = FooBar("Hello")
some_method(foobar, "World")
bar(FooBar.foo)
Cela imprimera "Bonjour le monde"
Beaucoup de bonnes réponses mais étrange que personne n'ait mentionné l'utilisation d'une fonction lambda
.
Donc, si vous n’avez pas d’arguments, les choses deviennent assez triviales:
def method1():
return 'hello world'
def method2(methodToRun):
result = methodToRun()
return result
method2(method1)
Mais disons que vous avez un (ou plusieurs) arguments dans method1
:
def method1(spam):
return 'hello ' + str(spam)
def method2(methodToRun):
result = methodToRun()
return result
Ensuite, vous pouvez simplement invoquer method2
Comme method2(lambda: method1('world'))
.
method2(lambda: method1('world'))
>>> hello world
method2(lambda: method1('reader'))
>>> hello reader
Je trouve cela beaucoup plus propre que les autres réponses mentionnées ici.
Les méthodes sont des objets comme les autres. Ainsi, vous pouvez les faire circuler, les stocker dans des listes et des dictionnaires, faire ce que vous voulez avec eux. La particularité d’eux est qu’ils sont des objets appelables afin que vous puissiez invoquer __call__
Dessus. __call__
Est appelé automatiquement lorsque vous appelez la méthode avec ou sans arguments, il vous suffit donc d'écrire methodToRun()
.