Python __slots__

定义了 __slots__ 静态属性的类没有 __dict__ 属性。而且只能添加存在于槽中的属性(可以少加,不能多加)。

class Point:
    __slots__ = ['x', 'y']
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(1, 2)
print(p.__dict__)  # 输出: AttributeError: 'Point' object has no attribute '__dict__'

槽最大的意义在于节省空间:共享 __slots__,每个对象没有自己的 __dict__。节省了字典的空间。对于属性较多的对象,使用槽访问速度可能会下降。

>>> import sys
>>> class Foo:
...    def __init__(self, x): self.x = x
...
>>> sys.getsizeof(Foo(1))
56
>>> sys.getsizeof(Foo(1)) + sys.getsizeof(Foo(1).__dict__)
336
>>> class Bar:
...    __slots__ = 'x', # 这里表示的是一个元组
...    def __init__(self, x): self.x = x
...
>>> sys.getsizeof(Bar(1))
40

有些属性可能既不存在于 __slots__ 中,又不存在于 __dict__ 中。这些属性是方法,能从 dir(obj) 中看到。而且标注了 @property 的方法能够直接像其他属性一样访问。