Можно ли передать метод в качестве параметра методу?
self.method2(self.method1)
def method1(self):
return 'hello world'
def method2(self, methodToRun):
result = methodToRun.call()
return result
Можно ли передать метод в качестве параметра методу?
self.method2(self.method1)
def method1(self):
return 'hello world'
def method2(self, methodToRun):
result = methodToRun.call()
return result
Да, это так, просто используйте название метода, как вы написали. Методы/функции являются объектами в Python, как и все остальное, и вы можете передавать их так же, как вы делаете переменные. Фактически, вы можете думать о методе (или функции) как о переменной, значением которой является фактический вызываемый объект кода.
К вашему сведению, метода call
нет - я думаю, что он называется __call__
, но вам не нужно вызывать его явно:
def method1():
return 'hello world'
def method2(methodToRun):
result = methodToRun()
return result
method2(method1)
Если вы хотите, чтобы method1
вызывался с аргументами, то все становится немного сложнее. method2
должен быть написан с небольшим количеством информации о том, как передавать аргументы в method1
, и он должен получить значения для этих аргументов откуда-то. Например, если method1
должен принимать один аргумент:
def method1(spam):
return 'hello ' + str(spam)
тогда вы могли бы написать method2
для вызова его с одним аргументом, который передается в:
def method2(methodToRun, spam_value):
return methodToRun(spam_value)
или с аргументом, что он вычисляет сам:
def method2(methodToRun):
spam_value = compute_some_value()
return methodToRun(spam_value)
Вы можете расширить это для других комбинаций значений, переданных и значений, вычисленных, как
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)
или даже с аргументами ключевых слов
def method2(methodToRun, ham_value):
spam_value = compute_some_value()
return methodToRun(spam_value, ham=ham_value)
Если вы не знаете, когда пишете method2
, какие аргументы будет принимать methodToRun
, вы также можете использовать распаковку аргумента для его вызова в общем виде:
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'})
В этом случае positional_arguments
должен быть списком, кортежем или чем-то подобным, а keyword_arguments
является keyword_arguments
или keyword_arguments
. В method2
вы можете изменить positional_arguments
и keyword_arguments
(например, чтобы добавить или удалить определенные аргументы или изменить значения) перед вызовом method1
.
Да, это возможно. Просто назовите его:
class Foo(object):
def method1(self):
pass
def method2(self, method):
return method()
foo = Foo()
foo.method2(foo.method1)
Вот ваш пример, переписанный для показа отдельного рабочего примера:
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()
Да; функции (и методы) являются объектами первого класса в Python. Следующие работы:
def foo(f):
print "Running parameter f()."
f()
def bar():
print "In bar()."
foo(bar)
Выходы:
Running parameter f().
In bar().
На такие вопросы легко ответить, используя интерпретатор Python или, для дополнительных возможностей, оболочку IPython.
Методы - это объекты, подобные любым другим. Таким образом, вы можете передавать их, хранить в списках и диктофонах, делать с ними все, что вам нравится. Особая вещь о них - это вызываемые объекты, поэтому вы можете вызвать __call__
на них. __call__
автоматически вызывается при вызове метода с аргументами или без них, поэтому вам просто нужно написать methodToRun()
.
Если вы хотите передать метод класса в качестве аргумента, но у вас еще нет объекта, для которого вы собираетесь его вызывать, вы можете просто передать объект, как только он у вас появится в качестве первого аргумента (то есть "я") аргумент).
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)
Это напечатает "Hello World"
Много хороших ответов, но странно, что никто не упомянул использование lambda
функции.
Так что, если у вас нет аргументов, все становится довольно тривиально:
def method1():
return 'hello world'
def method2(methodToRun):
result = methodToRun()
return result
method2(method1)
Но скажем, у вас есть один (или несколько) аргументов в method1
:
def method1(spam):
return 'hello ' + str(spam)
def method2(methodToRun):
result = methodToRun()
return result
Затем вы можете просто вызвать method2
как method2(lambda: method1('world'))
.
method2(lambda: method1('world'))
>>> hello world
method2(lambda: method1('reader'))
>>> hello reader
Я считаю, что это намного чище, чем другие ответы, упомянутые здесь.