【问题标题】:Passing data accross Classess with out instantiating the class跨类传递数据而不实例化类
【发布时间】:2026-02-11 01:15:01
【问题描述】:

我有两个类需要在彼此之间传递数据。第一个类实例化第二个。第二类需要能够将信息传递回第一类。但是我不能从第二类再次实例化ClassOne。两个类都运行一个共享计时器,它们在其中轮询不同的事物,因此当它们共享计时器时,它们不能共享它们轮询的对象。

我目前的解决方案(有效)是将一个方法传递给ClassTwo 并用于发送数据备份,但我觉得这可能有点老套,而且是错误的做法。

classOne():

    def __init__(self,timer):
        self.classTwo = classTwo(self.process_alerts,timer)
        self.classTwo.start

    def process_alerts(alert_msg):
        print alert_msg 


classTwo():

    def __init__(proses_alerts,timer)
        self.process_alerts = process_alerts  # <----- class ones method

    def start(self):
        check for alerts:
            if alert found: 
                self.alert(alert_msg)


    def alert(self,alert_msg):
        self.process_alert(alert_msg)  # <----- ClassOnes method

感谢您的宝贵时间。

【问题讨论】:

  • 未来提示:在注释中添加标记,这样代码仍然有效:)。
  • 可以将@staticmethod注解添加到process_alerts
  • 你为什么不从第一类继承第二类呢? class Two(One): ...
  • 因为我使用的计时器应用程序重载了 3 个方法,所以两个类都需要在其中包含这些方法并返回不同的信息。
  • 我看不出矛盾。

标签: python oop


【解决方案1】:

您可以删除/最小化类之间的耦合!我发现这种architecture 非常适合通过Queue 通信来共享数据。

通过使用 Queue,您可以解耦这两个类。生产者 (ClassTwo) 可以检查消息,并将它们发布到队列中。它不再需要知道如何正确地实例化一个类或与之交互,它只是传递一条消息。

然后,当消息可用时,ClassOne 实例可以从队列中提取消息。这也有助于扩展彼此独立的每个实例。

ClassTwo -> publish to queue -> Class One pulls from queue.

这也有助于测试,因为这两个类是完全隔离的,您可以为任一类提供一个队列。


队列通常还提供支持阻塞直到消息可用的操作,因此您不必管理超时。

【讨论】:

  • 非常感谢您的回答。就我而言,布鲁诺的回答没有实施任何额外的措施就成功了,所以我将他标记为正确。
【解决方案2】:

没有什么能阻止您将当前的 ClassOne 实例 (self) 传递给它自己的 ClassTwo 实例:

class ClassOne(object):
    def __init__(self):
        self.two = ClassTwo(self)
        self.two.start()

   def process_alert(self, msg):
       print msg

class ClassTwo(object):
    def __init__(self, parent):
        self.parent = parent

    def start(self):
        while True:
            if self.has_message():
                self.parent.process_alert(self.get_message())

请注意,在此上下文中,“父”表示它是一种包含关系(“has a”),与继承无关(“is a”)。

如果ClassOne 负责实例化ClassTwo (这确实引入了强耦合),您可以更改ClassOne,这样它需要一个工厂:

class ClassOne(object):
    def __init__(self, factory):
        self.other = factory(self)
        self.other.start()

#等

然后将ClassTwo作为工厂传递:

c1 = ClassOne(ClassTwo)  

因此,您实际上可以传递任何返回具有正确接口的对象(使单元测试更容易)

或者 - 至少在你的(我假设是精简的)示例中 - 你可以让 ClassOne 将自己传递给 ClassTwo.start() 并明确地将 ClassTwo 实例传递给 ClassOne,即:

class ClassOne(object):
    def __init__(self, other):
        self.other.start(self)

    def process_alert(self, msg):
        print msg


class ClassTwo(object):
    def start(self, parent):
        while True:
            if self.has_message():
                parent.process_alert(self.get_message())


c2 = ClassTwo()
c1 = ClassOne(c2)

或者甚至更简单地从ClassOne 中删除对ClassTwo.start 的调用,并且您不需要对ClassOne.__init__ 中的ClassTwo 实例的任何引用:

class ClassOne(object):

    def process_alert(self, msg):
        print msg


class ClassTwo(object):
    def start(self, parent):
        while True:
            if self.has_message():
                parent.process_alert(self.get_message())


c1 = ClassOne()
c2 = ClassTwo()
c2.start(c1)

它尽可能地解耦,但只有在ClassTwo 只需要start() 中的ClassOne 实例并且从startClassOne 调用的方法不需要在@ 上保留引用时才有效987654346@ 实例。

【讨论】:

    最近更新 更多