如何在Python中调用实例创建者的函数?

1 投票
3 回答
1021 浏览
提问于 2025-04-17 08:48

我有两个模块,每个模块里都有一个类。
我的主程序创建了一个类One的对象,这个对象又创建了很多类Two的对象。
我需要能够从类Two的实例中调用类One里的一个函数。
下面是我目前的情况:

模块 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()作为参数传给类Two,像这样:

self.new_instance = Two(self.call_back_func)

但我想知道有没有更好的方法来实现这个功能。

3 个回答

0

我觉得你这里缺少了一个对象。具体来说,是 创建者模式

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
1

你所做的事情是完全正确的。注意,__init__ 不是构造函数。它只是一个初始化的方法。 (__new__ 才是 Python 的构造函数)

关于这个话题的更多信息可以在问题 Python 中 __new__ 和 __init__ 的使用? 中找到。

2

我觉得这里有个简单性和松耦合之间的权衡。在我看来,简单的做法是把回调函数传给一个对象,而松耦合的做法则是使用一个框架来在对象之间传递信号。

举个例子,如果你使用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)框架。当创建一个按钮组件时,并不需要传递一个回调函数来处理按钮被点击时的操作。然而,按钮会发出一个点击信号,任何订阅了这个信号的回调函数都会被执行,从而完成所需的操作。

撰写回答