You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:28:38