观察者模式实现pyqt的信号+槽。方便类间的动态的消息传递

python中对象之间怎么传递信息?
只是:这个接口直接是作为一个子类存在。印象中接口应该是可以动态调用各个子类(还可以根据情况继续添加新的子类,调用者不变,只是具体实现可以变化)

class SignalSlot(object):

    def __init__(self):
        self._SSPool = dict()

    def connect(self, signal, slot):
        if signal not in self._SSPool:
            self._SSPool[signal] = list()
        if slot not in self._SSPool[signal]:
            self._SSPool[signal].append(slot)

    def disconnect(self, signal, slot):
        if signal not in self._SSPool:
            pass
        elif slot not in self._SSPool[signal]:
            pass
        else:
            self._SSPool[signal].remove(slot)

    def emit(self, signal, args):
        slots = list()
        if signal in self._SSPool:
            slots = self._SSPool[signal]
        for slot in slots:
            slot(*args)


class Interface(SignalSlot):
    """# signals"""

    def value_changed(self):
        self.emit("value_changed", ())

    def input_done(self, text):
        self.emit("input_done", (text,))

    def scroll(self, x, y):
        self.emit("scroll", (x, y))


class User(object):
    """# slots"""

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

    def value_changed(self):
        print(f"[{self.name}]value_changed-User")

    def input_done(self, text):
        print(f"[{self.name}]input_done-User the text is:", text)

    def scroll(self, x, y):
        print(f"[{self.name}]scroll-User go to (%d:%d)" % (x, y))


inf = Interface()
user1 = User("user1")
user2 = User("user2")

inf.connect("value_changed", user1.value_changed)
inf.connect("value_changed", user1.value_changed)
inf.connect("value_changed", user2.value_changed)

inf.connect("input_done", user1.input_done)

inf.connect("scroll", user2.scroll)

inf.value_changed()
inf.input_done("my name is Tim")
inf.scroll(100, 200)

"""
[user1]value_changed-User
[user2]value_changed-User
[user1]input_done-User the text is: my name is Tim
[user2]scroll-User go to (100:200)
"""

《精通Python设计模式》作者: [荷] Sakis Kasampalis,第13章 观察者模式代码:

class Publisher:

    def __init__(self):
        self.observers = []

    def add(self, observer):
        if observer not in self.observers:
            self.observers.append(observer)
        else:
            print('Failed to add: {}'.format(observer))

    def remove(self, observer):
        try:
            self.observers.remove(observer)
        except ValueError:
            print('Failed to remove: {}'.format(observer))

    def notify(self):
        [o.notify(self) for o in self.observers]


class DefaultFormatter(Publisher):

    def __init__(self, name):
        Publisher.__init__(self)
        self.name = name
        self._data = 0

    def __str__(self):
        return "{}: '{}' has data = {}".format(type(self).__name__, self.name, self._data)

    @property
    def data(self):
        return self._data

    @data.setter
    def data(self, new_value):
        try:
            self._data = int(new_value)
        except ValueError as e:
            print('Error: {}'.format(e))
        else:
            self.notify()


class HexFormatter:

    def notify(self, publisher):
        print("{}: '{}' has now hex data = {}".format(type(self).__name__,
                                                      publisher.name, hex(publisher.data)))


class BinaryFormatter:

    def notify(self, publisher):
        print("{}: '{}' has now bin data = {}".format(type(self).__name__,
                                                      publisher.name, bin(publisher.data)))


def main():
    df = DefaultFormatter('test1')
    print(df)

    print()
    hf = HexFormatter()
    df.add(hf)
    df.data = 3
    print(df)

    print()
    bf = BinaryFormatter()
    df.add(bf)
    df.data = 21
    print(df)

    print()
    df.remove(hf)
    df.data = 40
    print(df)

    print()
    df.remove(hf)
    df.add(bf)
    df.data = 'hello'
    print(df)

    print()
    df.data = 15.8
    print(df)
    
    """
    DefaultFormatter: 'test1' has data = 0

    HexFormatter: 'test1' has now hex data = 0x3
    DefaultFormatter: 'test1' has data = 3
    
    HexFormatter: 'test1' has now hex data = 0x15
    BinaryFormatter: 'test1' has now bin data = 0b10101
    DefaultFormatter: 'test1' has data = 21
    
    BinaryFormatter: 'test1' has now bin data = 0b101000
    DefaultFormatter: 'test1' has data = 40
    
    Failed to remove: <__main__.HexFormatter object at 0x0000018211EFBE48>
    Failed to add: <__main__.BinaryFormatter object at 0x0000018211EFBE80>
    Error: invalid literal for int() with base 10: 'hello'
    DefaultFormatter: 'test1' has data = 40
    
    BinaryFormatter: 'test1' has now bin data = 0b1111
    DefaultFormatter: 'test1' has data = 15
    """

if __name__ == '__main__':
    main()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值