静态属性和实例属性
非常惭愧,在开发维护 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
来读写属性,这是其一。
其二,我经过全局搜索发现,所有涉及的类都只被实例化了一次。
其三,软件的功能基本可以正常工作,只是偶尔出现的卡顿可能与这个问题有关。
也就是说,理论上,在修改前后,代码的整体逻辑很相近,只是埋了一个以后要拓展功能时很可能会踩的坑。