232

是否可以将方法作为参数传递给方法?

self.method2(self.method1)

def method1(self):
    return 'hello world'

def method2(self, methodToRun):
    result = methodToRun.call()
    return result
4

9 回答 9

309

是的,只需使用您所写的方法名称即可。方法和函数是 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是一个字典或类似的。在调用之前,method2您可以修改positional_argumentsand keyword_arguments(例如添加或删除某些参数或更改值)method1

于 2009-04-01T18:09:03.977 回答
38

是的,有可能。只需调用它:

class Foo(object):
    def method1(self):
        pass
    def method2(self, method):
        return method()

foo = Foo()
foo.method2(foo.method1)
于 2009-04-01T18:11:42.707 回答
16

这是您重新编写的示例以显示一个独立的工作示例:

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()
于 2009-04-01T18:13:07.820 回答
11

使用一个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

然后你可以简单地调用method2as method2(lambda: method1('world'))

method2(lambda: method1('world'))
>>> hello world
method2(lambda: method1('reader'))
>>> hello reader

我发现这比这里提到的其他答案要干净得多。

于 2019-06-12T00:39:48.407 回答
9

如果您想将类的方法作为参数传递,但还没有要调用它的对象,则可以在将对象作为第一个参数(即“自我”争论)。

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”

于 2018-06-13T17:12:17.613 回答
8

是的; 函数(和方法)是 Python 中的第一类对象。以下作品:

def foo(f):
    print "Running parameter f()."
    f()

def bar():
    print "In bar()."

foo(bar)

输出:

Running parameter f().
In bar().

使用 Python 解释器或使用IPython shell 来回答这些问题是微不足道的。

于 2009-04-01T18:11:47.277 回答
4

方法和其他对象一样是对象。所以你可以传递它们,将它们存储在列表和字典中,对它们做任何你喜欢的事情。它们的特殊之处在于它们是可调用的对象,因此您可以__call__对其进行调用。__call__当您调用带有或不带参数的方法时会自动调用,因此您只需要编写methodToRun().

于 2009-04-01T18:14:52.980 回答
3

不完全是您想要的,但一个相关的有用工具是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')()
于 2020-04-16T01:35:09.973 回答
2

示例:一个简单的函数调用包装器:

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
于 2020-11-11T06:47:24.203 回答