Python,如何从实例方法“自动”调用函数/方法?

Posted

技术标签:

【中文标题】Python,如何从实例方法“自动”调用函数/方法?【英文标题】:Python, How to "automatically" call a function/method from an instance method? 【发布时间】:2015-09-11 09:12:32 【问题描述】:

有没有办法强制 Python 中的实例方法在执行之前调用另一个方法?

一个简单的演示示例:

class MyClass(object):
  def __init__(self):
    pass
  def initialize(self):
    print "I'm doing some initialization"
  def myfunc(self):
    print "This is myfunc()!"

我想要一些方法让 myfunc() 在运行之前自动调用 initialize()。如果我这样做:

obj = MyClass()
obj.myfunc()

我希望看到以下输出:

I'm doing some initialization 
This is myfunc()!

无需在 myfunc() 中显式调用 initialize()。

原因是如果我有很多“myfunc”实例,比如 myfunc1、myfunc2、myfunc3,都需要调用“initialize”,我宁愿让它们都在同一个地方调用一次初始化,如反对每次手动调用该方法。这是元类可以做到的吗?

【问题讨论】:

您要解决什么问题?初始化成本高吗?为什么不在初始化程序 __init__ 中做呢? 您对为什么不想在myfunc() 中简单地调用initialize() 的解释对我来说毫无意义。 我正在侦听消息队列 (Rabbit) 上的事件。不同的事件触发不同的回调,对应于类上的方法。初始化并不昂贵,但每次调用回调时它都需要是唯一的。例如,我有一个唯一的“log_tag”值,对于任何回调调用都必须是唯一的。我可以在 myfuncN() 的每个变体中调用 initialize(),只是看起来不太干。 【参考方案1】:

您可以在 Python 中使用装饰器。让装饰器在调用之前调用你想要的函数。您将能够在所有想要的功能中使用装饰器。这是语法糖。

【讨论】:

啊,没想到用装饰器。我想这会做我想要的......我会试一试。 请举例说明如何做到这一点,也许是functools.wrap【参考方案2】:

你可以做一个包装函数:

def wrapper(self, func_name):
    self.initialize()
    self.func_name()

def myfunc1(self):
    # do something

def myfunc2(self):
    # do something

obj.wrapper(myfunc1)
obj.wrapper(myfunc2)

【讨论】:

【参考方案3】:

self.initialize() 添加到myfunc(),这应该可以满足您的需求。

class MyClass(object):
    def __init__(self):
       pass
    def initialize(self):
       print("I'm doing some initialization")
    def myfunc(self):
       self.initialize()
       print("This is myfunc()!")

试试:

>>> a = MyClass()
>>> a.myfunc()
I'm doing some initialization
This is myfunc()!

编辑: 但是,实践是按照 DevShark 的建议使用 decorators

在另一篇文章中有讨论,见Python decorators in classes

【讨论】:

这就是我想知道是否可以避免的。如果我有 10 或 100 个“myfuncN()”方法,那么我将在每个方法中调用 initialize()。根据上面的帖子,我认为装饰器是我想要的。

以上是关于Python,如何从实例方法“自动”调用函数/方法?的主要内容,如果未能解决你的问题,请参考以下文章

Python——类和对象

python成员函数如何调用静态函数

python类与对象-如何通过实例方法名字的字符串调用方法

Python构造函数

类方法:绑定或无绑定

如何实例化一个 vba 类并从 vb.net 调用一个方法?