Можно ли передать метод в качестве параметра методу?
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 методы и функции являются объектами, как и все остальное, и вы можете передавать их так же, как и переменные. Фактически, вы можете думать о методе (или функции) как о переменной, значение которой является фактическим вызываемым объектом кода.
Поскольку вы спрашивали о методах, я использую методы в следующих примерах, но обратите внимание, что все, что ниже, одинаково применимо к функциям (за исключением параметра self
).
Чтобы вызвать переданный метод или функцию, вы просто используете имя, к которому она привязана, так же, как вы использовали бы обычное имя метода (или функции):
def method1(self):
return 'hello world'
def method2(self, methodToRun):
result = methodToRun()
return result
obj.method2(obj.method1)
Примечание. Я считаю, что метод __call__()
действительно существует, т.е. вы можете технически использовать methodToRun.__call__()
, но вам, вероятно, никогда не следует делать это явно. __call__()
предназначен для реализации, а не для вызова из вашего собственного кода.
Если вы хотите, чтобы method1
вызывался с аргументами, все становится немного сложнее. method2
должен быть написан с небольшой информацией о том, как передавать аргументы в method1
, и он должен откуда-то получать значения для этих аргументов. Например, если method1
должен принимать один аргумент:
def method1(self, spam):
return 'hello ' + str(spam)
тогда вы можете написать method2
, чтобы вызвать его с одним переданным аргументом:
def method2(self, methodToRun, spam_value):
return methodToRun(spam_value)
или с аргументом, который вычисляет сам:
def method2(self, methodToRun):
spam_value = compute_some_value()
return methodToRun(spam_value)
Вы можете расширить это до других комбинаций переданных значений и вычисленных значений, например
def method1(self, spam, ham):
return 'hello ' + str(spam) + ' and ' + str(ham)
def method2(self, methodToRun, ham_value):
spam_value = compute_some_value()
return methodToRun(spam_value, ham_value)
или даже с аргументами ключевого слова
def method2(self, methodToRun, ham_value):
spam_value = compute_some_value()
return methodToRun(spam_value, ham=ham_value)
Если при написании method2
вы не знаете, какие аргументы будут принимать methodToRun
, вы также можете использовать распаковку аргументов, чтобы вызвать его обычным способом:
def method1(self, spam, ham):
return 'hello ' + str(spam) + ' and ' + str(ham)
def method2(self, methodToRun, positional_arguments, keyword_arguments):
return methodToRun(*positional_arguments, **keyword_arguments)
obj.method2(obj.method1, ['spam'], {'ham': 'ham'})
В этом случае positional_arguments
должен быть списком, кортежем или подобным, а keyword_arguments
- dict или подобным. В method2
вы можете изменить positional_arguments
и keyword_arguments
(например, добавить или удалить определенные аргументы или изменить значения) перед вызовом method1
.
method
с function
. def method1(spam):
- это определение функции, а не определение метода.
- person Michael Dorst; 25.08.2020
func(obj.method)
. Вы объяснили, как передать функцию в качестве параметра, например. func(other_func)
, но пока относится к функциям как к методам. Я нашел это очень запутанным.
- person Michael Dorst; 25.08.2020
Да, это возможно. Просто назовите это:
class Foo(object):
def method1(self):
pass
def method2(self, method):
return method()
foo = Foo()
foo.method2(foo.method1)
foo
нет?
- person Lei Yang; 26.07.2017
def method1(): pass def method2(method) return method() method2(method1)
- person Tom; 16.10.2017
Вот ваш пример, переписанный, чтобы показать автономный рабочий пример:
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.
Если вы хотите передать метод класса в качестве аргумента, но еще не имеете объекта, для которого вы собираетесь его вызвать, вы можете просто передать объект, как только он будет у вас в качестве первого аргумента (т.е. аргумент).
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(param):
return 'hello ' + str(param)
def method2(methodToRun):
result = methodToRun()
return result
Затем вы можете просто вызвать method2
как method2(lambda: method1('world'))
.
method2(lambda: method1('world'))
>>> hello world
method2(lambda: method1('reader'))
>>> hello reader
Я считаю это намного чище, чем другие ответы, упомянутые здесь.
()
в конце объекта в моем обратном вызове, да.
- person vaponteblizzard; 12.06.2020
Методы - это такие же объекты, как и любые другие. Так что вы можете передавать их, хранить в списках и диктовках, делать с ними все, что захотите. Их особенность заключается в том, что они являются вызываемыми объектами, поэтому вы можете вызывать для них __call__
. __call__
вызывается автоматически, когда вы вызываете метод с аргументами или без них, поэтому вам просто нужно написать methodToRun()
.
Не совсем то, что вам нужно, но связанный полезный инструмент - getattr()
, чтобы использовать имя метода в качестве параметра.
class MyClass:
def __init__(self):
pass
def MyMethod(self):
print("Method ran")
# Create an object
object = MyClass()
# Get all the methods of a class
method_list = [func for func in dir(MyClass) if callable(getattr(MyClass, func))]
# You can use any of the methods in method_list
# "MyMethod" is the one we want to use right now
# This is the same as running "object.MyMethod()"
getattr(object,'MyMethod')()
Пример: простая оболочка вызова функции:
def measure_cpu_time(f, *args):
t_start = time.process_time()
ret = f(*args)
t_end = time.process_time()
return t_end - t_start, ret