Respostas:
Sim, é só usar o nome do método, como você escreveu. Métodos / funções são objetos em Python, como qualquer outra coisa, e você pode transmiti-los da mesma maneira que faz variáveis. De fato, você pode pensar em um método (ou função) como uma variável cujo valor é o objeto de código realizável.
Para sua informação, não há call
método - acho que é chamado __call__
, mas você não precisa invocá-lo explicitamente:
def method1():
return 'hello world'
def method2(methodToRun):
result = methodToRun()
return result
method2(method1)
Se você quiser method1
ser chamado com argumentos, as coisas ficam um pouco mais complicadas. method2
precisa ser escrito com um pouco de informação sobre como passar argumentos method1
e precisa obter valores para esses argumentos de algum lugar. Por exemplo, se você method1
deve receber um argumento:
def method1(spam):
return 'hello ' + str(spam)
então você pode escrever method2
para chamá-lo com um argumento que é passado:
def method2(methodToRun, spam_value):
return methodToRun(spam_value)
ou com um argumento que se calcula:
def method2(methodToRun):
spam_value = compute_some_value()
return methodToRun(spam_value)
Você pode expandir isso para outras combinações de valores passados e valores calculados, como
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 mesmo com argumentos de palavra-chave
def method2(methodToRun, ham_value):
spam_value = compute_some_value()
return methodToRun(spam_value, ham=ham_value)
Se você não souber, ao escrever method2
, quais methodToRun
argumentos serão utilizados, também poderá usar a descompactação de argumentos para chamá-lo de maneira genérica:
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'})
Nesse caso, positional_arguments
precisa ser uma lista ou tupla ou similar e keyword_arguments
é um ditado ou semelhante. Em method2
que você pode modificar positional_arguments
e keyword_arguments
(por exemplo, para adicionar ou remover certos argumentos ou alterar os valores) antes de chamar method1
.
Sim, é possível. Basta chamá-lo:
class Foo(object):
def method1(self):
pass
def method2(self, method):
return method()
foo = Foo()
foo.method2(foo.method1)
def method1(): pass def method2(method) return method() method2(method1)
Aqui está seu exemplo reescrito para mostrar um exemplo de trabalho independente:
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()
Sim; funções (e métodos) são objetos de primeira classe em Python. Os seguintes trabalhos:
def foo(f):
print "Running parameter f()."
f()
def bar():
print "In bar()."
foo(bar)
Saídas:
Running parameter f().
In bar().
É fácil responder a esse tipo de perguntas usando o interpretador Python ou, para mais recursos, o shell IPython .
Se você deseja passar o método de uma classe como argumento, mas ainda não possui o objeto para o qual irá chamá-lo, basta passar o objeto assim que tiver o primeiro argumento (ou seja, o "eu") argumento).
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)
Isso imprimirá "Olá Mundo"
Muitas respostas boas, mas estranhas que ninguém mencionou usando uma lambda
função.
Portanto, se você não tem argumentos, as coisas se tornam bastante triviais:
def method1():
return 'hello world'
def method2(methodToRun):
result = methodToRun()
return result
method2(method1)
Mas digamos que você tenha um (ou mais) argumentos em method1
:
def method1(param):
return 'hello ' + str(param)
def method2(methodToRun):
result = methodToRun()
return result
Então você pode simplesmente chamar method2
como method2(lambda: method1('world'))
.
method2(lambda: method1('world'))
>>> hello world
method2(lambda: method1('reader'))
>>> hello reader
Acho isso muito mais limpo do que as outras respostas mencionadas aqui.
()
no final do objeto na minha chamada de retorno, duh.
Métodos são objetos como qualquer outro. Assim, você pode distribuí-los, armazená-los em listas e ditados, fazer o que quiser com eles. A coisa especial sobre eles é que eles são objetos que podem ser chamados para que você possa invocá __call__
-los. __call__
é chamado automaticamente quando você invoca o método com ou sem argumentos, então você só precisa escrever methodToRun()
.
Não é exatamente o que você deseja, mas uma ferramenta útil relacionada é getattr()
usar o nome do método como parâmetro.
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')()
foo
?