如何在python中调用实例创建者的函数?
我有2个模块,每个模块都包含一个类。
我的主程序实例化了一个类的对象,它实例化了许多类的对象。
我需要能够从第二类的实例中调用第一类函数。
这是什么,我有一个大致的样子:如何在python中调用实例创建者的函数?
模块mod_one.py:
import mod_two
class One:
def __init__(self):
self.new_instance = Two()
def call_back_func(self):
# This function should be called
# from the new instance of class Two()
模块mod_two.py:
class Two:
def __init__(self):
# Call call_back_func() of module mod_one
我发现的唯一途径是通过回调函数call_back_func()作为第二类的参数,如下所示:
self.new_instance = Two(self.call_back_func)
但我想知道是否有更好的方法来做到这一点。
你在做什么是完全有效的。请注意,__init__
不是构造函数。它是只是的一种初始化方法。 (__new__
是Python的构造函数方法)
更多关于这个话题可以讨论Python's use of __new__ and __init__?
-1:我无法看到'__init__'与其他语言的构造函数的概念不同。 '__new__' OTOH是一种在Java/C++等语言中不存在的概念,所以我不明白怎么说它更适合这个概念。我认为“'__init__'不是构造函数”是一个神话,并且是一个毫无帮助的。官方的python文档甚至提到'__init__'作为构造函数! http://docs.python.org/reference/datamodel.html#basic-customization – Ben 2011-12-21 20:44:27
对象构造在离开__new__时完成... – gecco 2011-12-21 21:01:52
在输入构造函数之前,它向成员分配值。正如在Java和C++中一样。唯一的区别是它们不提供像'__new__'这样的工具来自定义新实例的过程。 – Ben 2011-12-21 21:11:07
我觉得你在这里失踪的对象被发现。具体的Creational Builder Pattern
class OneTwoBuilder:
def createOne(self, num_of_two=0):
o = One()
child = []
for _ in xrange(num_of_two):
t = Two()
o.callback(t)
child.append(t)
o.setChilds(child)
return o
我觉得有一个权衡这里简单性和松耦合之间。在我看来,简单性就是将回调传递给一个对象,而松耦合则是使用一个框架在对象之间传递信号。
举例来说,如果你使用blinker信号库,您可以使用此替代设计:
from blinker import signal
class One:
def __init__(self):
self.two = Two()
self.two.some_signal.connect(self.callback)
def callback(self, data):
print 'Called'
class Two:
some_signal = signal('some_signal')
def process(self):
# Do something
self.some_signal.send()
one = One()
one.two.process()
在上面的代码中,Two
对象甚至不知道是否有其他物体关心其内部状态改变。但是,它通过发出可能被其他对象使用的信号(在本例中为One
对象)来执行某些特定操作来通知它们。
这种方法的一个很好的例子是GUI框架。当一个按钮小部件被创建时,不需要传递一个回调,该按钮被点击时应该被执行。然而,该按钮发出点击信号,并且无论订阅哪个回调信号都被执行以执行期望的动作。
谢谢,我会试试看,尽管上面的评论鼓励我“不修复它如果它没有坏“:) – user1102018 2011-12-21 20:05:35
我同意这些意见,我相信你只需要知道其他的替代方案,以防万一以后你发现你传递了太多的回调。 – jcollado 2011-12-21 20:21:58
我来这里用blinker来说明如何在发出信号时如何调用对象的方法。我发现你的例子非常有用,谢谢。 – Jabba 2013-06-28 15:28:32
这是一个非常有效的方法,因为它不会引入循环依赖。 – 2011-12-21 18:29:15
我认为将'self.call_back_func'传递给构造函数是一个很好的方法。 – NPE 2011-12-21 18:29:17