如何让Python类变量MyClass拥有Signal般的实例唯一性?
问题解析与解决方案
为什么Signal和MyClass实例ID表现不同
- Signal的特殊机制:PySide2中的
Signal是Qt元对象系统的特殊类型,在类级别定义后,每个PSClass实例化时,Qt会为该实例生成独立的Signal实例。类级别的Signal定义只是一个模板,每个对象都会拥有专属的Signal实例,因此ID唯一。 - MyClass实例的类属性特性:
onMySignal = MyClass()是直接在类级别创建的类属性,所有PSClass的实例都会共享这个类属性对象,所以无论创建多少个实例,它们的onMySignal都是同一个对象,ID自然相同。
让MyClass表现与Signal一致的方法
方法1:将MyClass实例化移至__init__(推荐)
把MyClass的实例创建放到类的构造方法中,作为实例属性,这样每个PSClass实例都会拥有独立的MyClass对象:
from PySide2.QtCore import Signal, QObject class MyClass: pass class PSClass(QObject): onRequest = Signal(str) def __init__(self): super().__init__() self.onMySignal = MyClass() # 每个实例创建独立的MyClass对象 self.onRequest.connect(self.printSomething) def send(self, message:str): self.onRequest.emit(message) def printSomething(self, data:str): print(data) sample_01 = PSClass() sample_02 = PSClass() sample_01.send(f"Signal ID:{id(sample_01.onRequest)}, MyClass ID:{id(sample_01.onMySignal)}") sample_02.send(f"Signal ID:{id(sample_02.onRequest)}, MyClass ID:{id(sample_02.onMySignal)}")
运行后输出示例:
Signal ID:56331376, MyClass ID:15825248 Signal ID:56331392, MyClass ID:15825264
方法2:用描述符模拟Signal的行为
如果想保留类级别定义的形式,可以通过**描述符(Descriptor)**实现,让类属性在实例访问时动态创建新的MyClass实例(这也是Signal的底层实现逻辑):
from PySide2.QtCore import Signal, QObject class MyClass: pass class MyClassDescriptor: def __get__(self, instance, owner): if instance is None: return self # 为每个实例存储独立的MyClass对象 if not hasattr(instance, '_my_class_instance'): instance._my_class_instance = MyClass() return instance._my_class_instance class PSClass(QObject): onRequest = Signal(str) onMySignal = MyClassDescriptor() # 使用描述符定义类属性 def __init__(self): super().__init__() self.onRequest.connect(self.printSomething) def send(self, message:str): self.onRequest.emit(message) def printSomething(self, data:str): print(data) sample_01 = PSClass() sample_02 = PSClass() sample_01.send(f"Signal ID:{id(sample_01.onRequest)}, MyClass ID:{id(sample_01.onMySignal)}") sample_02.send(f"Signal ID:{id(sample_02.onRequest)}, MyClass ID:{id(sample_02.onMySignal)}")
内容的提问来源于stack exchange,提问作者Bear
相关产品推荐
相关产品推荐

