如何在 Python 中将方法作为参数传递[重复]

2025-02-20 09:23:00
admin
原创
30
摘要:问题描述:是否可以将方法作为参数传递给方法?self.method2(self.method1) def method1(self): return 'hello world' def method2(self, methodToRun): result = methodToRun.cal...

问题描述:

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

self.method2(self.method1)

def method1(self):
    return 'hello world'

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

解决方案 1:

是的,只需使用方法的名称,就像您写的那样。方法和函数是 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,并且需要从某个地方获取这些参数的值。例如,ifmethod1应该接受一个参数:

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_argumentskeyword_arguments(例如添加或删除某些参数或更改值)method1

解决方案 2:

是的,这是可能的。只需将其称为:

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

foo = Foo()
foo.method2(foo.method1)

解决方案 3:

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

我发现这比这里提到的其他答案更清晰。

解决方案 4:

这是重写的示例,以显示独立的工作示例:

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()

解决方案 5:

如果您想将某个类的方法作为参数传递,但还没有要调用该方法的对象,那么您只需将该对象作为第一个参数(即“self”参数)传递即可。

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”

解决方案 6:

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

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

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

foo(bar)

输出:

Running parameter f().
In bar().

使用 Python 解释器或IPython shell (获得更多功能)可以轻松回答这些问题。

解决方案 7:

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

解决方案 8:

虽然不完全是您想要的,但是一个相关的有用工具是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')()

解决方案 9:

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

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
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1325  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。它涵盖了从产品概念产生到产品退市的整个生命周期,通过整合跨部门团队、优化流程等方式,显著提升产品开发的效率和质量,进而为项目的成功奠定坚实基础。深入探究IPD流程的五个阶段与项目成功之间...
IPD流程分为几个阶段   4  
  华为作为全球知名的科技企业,其成功背后的管理体系备受关注。IPD(集成产品开发)流程作为华为核心的产品开发管理模式,其中的创新管理与实践更是蕴含着丰富的经验和深刻的智慧,对众多企业具有重要的借鉴意义。IPD流程的核心架构IPD流程旨在打破部门墙,实现跨部门的高效协作,将产品开发视为一个整体的流程。它涵盖了从市场需求分析...
华为IPD是什么   3  
  IPD(Integrated Product Development)研发管理体系作为一种先进的产品开发模式,在众多企业的发展历程中发挥了至关重要的作用。它不仅仅是一套流程,更是一种理念,一种能够全方位提升企业竞争力,推动企业持续发展的有效工具。深入探究IPD研发管理体系如何助力企业持续发展,对于众多渴望在市场中立足并...
IPD管理流程   3  
  IPD(Integrated Product Development)流程管理旨在通过整合产品开发流程、团队和资源,实现产品的快速、高质量交付。在这一过程中,有效降低成本是企业提升竞争力的关键。通过优化IPD流程管理中的各个环节,可以在不牺牲产品质量和性能的前提下,实现成本的显著降低,为企业创造更大的价值。优化产品规划...
IPD流程分为几个阶段   4  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用