python - 当使用组合而不是继承时,如何在 Python 中的兄弟对象之间进行通信

标签 python methods composition

我有一个由 2 个(不同的)子对象组成的父对象。 2 个子实例需要进行通信。例如,假设 child1 需要向 child2 发送一些内容:

import children

class Parent:
    def __init__(self):
        self.child1 = children.Child1(self.q)
        self.child2 = children.Child2(self.q)

parent = Parent()
parent.child1.send("string")

是否有推荐的模式来实现这一目标?


我能想到的最好办法是在两个对象之间创建一个队列。这是可行的,但它需要接收对象运行一个线程。例如:

parent.py:

import children
import queue
import time

class Parent:
    def __init__(self):
        
        self.q = queue.Queue()
        self.child1 = children.Child1(self.q)
        self.child2 = children.Child2(self.q)

parent = Parent()
parent.child1.send("string")
time.sleep(1)

children.py:

import threading

class Child1:

    def __init__(self, q):
        self.q = q

    def send(self, item):
        self.q.put(item)

class Child2:

    def __init__(self, q):
        self.q = q
        self.receiver = threading.Thread(target=self.worker, daemon=True).start()

    def worker(self):
        """Process the queue"""
        while True:
            item = self.q.get()
            print(f"{item} received")

实际上,我在队列中发送的“项目”是函数名称和参数列表。这基本上是命令模式,如here所述。 。但我不喜欢接收器线程的需要。

如果可以允许一个对象直接调用另一个对象中的方法,我会更愿意。 如果它们之间存在继承关系,并且有一个共同的父级,我也许可以使用super()来实现这一点:

class Child1:

    def send(self, function, arguments):
        super().child2.function(arguments)

但在我的例子中没有继承:只有组合。 有更好的办法吗?

最佳答案

只需构造子级并引用回父级:

class Child1:
    def __init__(self, parent):
        self.parent = parent

    def send(self, msg):
        self.parent.child2.print_out(msg)

class Child2:
    def __init__(self, parent):
        self.parent = parent

    def print_out(self, msg):
        print(msg)

class Parent:
    def __init__(self):
        self.child1 = Child1(self)
        self.child2 = Child2(self)

parent = Parent()
parent.child1.send("foo")

关于python - 当使用组合而不是继承时,如何在 Python 中的兄弟对象之间进行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66733039/

相关文章:

python - 稀疏 numpy 数组的局部敏感散列

python - plt.hist() 仅针对特定频率; Python

java - 如何在 Magic 8 Ball 程序中正确使用 Java 中的方法

python - 如何在Python的for循环中分割数组

Python:根据现有列将列添加到 CSV 文件

javascript - 如何根据点击的DOM节点来区分点击事件?

ruby-on-rails - Rspec 方法创建错误

c++ - 如何用STL编写仿函数?

kotlin - 如何将依赖项注入(inject) Kotlin 中的接口(interface)委托(delegate)?

vue.js - 使用 Vue Composition API 获取 API(脚本设置)