通过Classess传递数据而没有实例化类

时间:2017-06-26 11:20:03

标签: python oop

我有两个需要在彼此之间传递数据的类。第一个类实例化第二个。第二类需要能够将信息传递回第一类。但是我无法再从第二类实例化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

感谢您的时间。

2 个答案:

答案 0 :(得分: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())

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

如果你有什么错误ClassOne负责实现ClassTwo(确实会引入强耦合),你可以更改ClassOne以便它需要一个工厂:

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

#etc

然后将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)

甚至更简单地从ClassTwo.start移除对ClassOne的来电,您无需在ClassTwo中引用ClassOne.__init__个实例:

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只需要ClassOne中的start()个实例以及startClassOne调用的方法时才有效我们还需要在ClassTwo实例上保留一个引用。

答案 1 :(得分:2)

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

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

然后ClassOne实例可以从队列中提取消息,因为它们可用。这也可以很好地相互独立地缩放每个实例。

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

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

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