静态属性和实例属性

非常惭愧,在开发维护 InputShare 这个项目数月之后我才注意到了这个问题。

什么问题呢?

很简单,我混淆了 Python 中静态属性和实例属性的语法。

类的静态属性语法如下:

class Class:
    static_property_name = "value"

实例属性的语法如下:

class Class:
    def __init__(self):
        instance_property_name = "value"

为什么会混淆?

看起来很好区分,对吧?那我为什么会混淆呢?当然是写 JavaScript 写的。因为在 JavaScript 中的实例属性可以这么写:

class Class {
    // 这是实例属性
    propertyName1 = "value"

    constructor() {
        // 这也是实例属性
        this.propertyName2 = "value"
    }
}

具体是怎么混淆的?

这就导致我在 InputShare 的代码中,常常出现明明是实例属性,却写成了静态属性,比如:

class MouseButtonStateStore:
    def __init__(self):
        self.mouse_button = HID_MouseButton.MOUSE_BUTTON_NONE.value

    def mouse_down(self, button: HID_MouseButton):
        self.mouse_button |= button.value

    def mouse_up(self, button: HID_MouseButton):
        self.mouse_button ^= button.value

上面这段代码在改前是这样的:

class MouseButtonStateStore:
    mouse_button: int = HID_MouseButton.MOUSE_BUTTON_NONE.value

    def mouse_down(self, button: HID_MouseButton):
        self.mouse_button |= button.value

    def mouse_up(self, button: HID_MouseButton):
        self.mouse_button ^= button.value

那为什么之前没有发现?

如上面的代码所示,我即使使用了静态属性,但是在实例方法中依然是使用 self.xx 来读写属性,这是其一。

其二,我经过全局搜索发现,所有涉及的类都只被实例化了一次

其三,软件的功能基本可以正常工作,只是偶尔出现的卡顿可能与这个问题有关。

也就是说,理论上,在修改前后,代码的整体逻辑很相近,只是埋了一个以后要拓展功能时很可能会踩的坑。

点此查看原文