使用Composition而不是Inheritance时,如何在Python中的同级对象之间进行通信

pobjuy32  于 2023-01-01  发布在  Python
关注(0)|答案(2)|浏览(104)

我有一个父对象,它由两个(不同的)子对象组成,这两个子示例需要通信,例如,假设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")

有没有推荐的模式来实现这一点?
我能想到的最好的方法是在这两个对象之间创建一个Queue。这是可行的,但它需要接收对象运行一个线程。例如:

父对象.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)

儿童。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)

但在我的情况下没有继承权:只是作文。有更好的方法吗?

qoefvg9y

qoefvg9y1#

只需要构造一个引用回父节点的子节点:

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")
nnsrf1az

nnsrf1az2#

我相信您要找的是Façade Pattern
据推测,Parent不仅仅是一个名称空间;让Child1发送一些东西给Child2看起来像是Parent的一种行为,它的实现被抽象化了,隐藏在外表后面。

class Foo:

    def send_msg(self):
        return f'This is a message sent from {self.__class__.__name__}.'

class Bar:

    def receive_msg(self, msg):
        print(self.__class__.__name__, 'has received the following message:'
        print('\t', msg)

class Facade:

    def __init__(self):
        self.foo = Foo()
        self.bar = Bar()

    def foo_the_bar(self):
        self.bar.receive_msg(self.foo.send_msg())
>>> facade = Facade()
>>> facade.foo_the_bar()
Bar has received the following message:
     This is a message sent from Foo.

相关问题