说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
__slots__
是 Python 中的一个特殊属性,用于限制实例可以动态添加的属性。通常情况下,Python 的类实例可以动态地添加任意的属性。但是,如果你希望限制实例的属性只能是预先定义好的一组属性,可以通过 __slots__
属性来实现。
__slots__
属性是一个字符串组成的元组,包含了允许实例动态添加的属性名称。如果一个类定义了 __slots__
属性,那么类的实例只能有 __slots__
中指定的属性,不能添加额外的属性。
使用 __slots__
的主要目的是节省内存,因为 Python 对象的属性通常存储在一个字典中,这会占用额外的内存。而使用 __slots__
后,对象的属性被存储在固定大小的数组中,不再使用字典,从而节省了内存空间。
以下是一个简单的示例,说明了如何使用 __slots__
属性:
class Person:
__slots__ = ('name', 'age')
def __init__(self, name, age):
self.name = name
self.age = age
# 创建一个 Person 对象
person = Person('Alice', 30)
# 添加额外的属性
# person.address = '123 Street'
# 如果取消注释,会抛出 AttributeError: 'Person' object has no attribute 'address'
# 输出对象的属性
print(person.name) # 输出:Alice
print(person.age) # 输出:30
在这个示例中,Person 类定义了 __slots__
属性,指定了允许实例具有的属性名称为 'name' 和 'age'。当我们创建 Person 对象时,只能为对象设置这两个属性,如果尝试添加额外的属性(比如 address),会抛出 AttributeError 异常。这样就限制了实例可以动态添加的属性。
__slots__
允许我们显式地声明数据成员(如特征属性)并禁止创建 __dict__
和 __weakref__
(除非是在 __slots__
中显式地声明或是在父类中可用。)
相比使用 __dict__
可以显著节省空间。 属性查找速度也可得到显著的提升。
object.__slots__
这个类变量可赋值为字符串、可迭代对象或由实例使用的变量名组成的字符串序列。 __slots__
会为已声明的变量保留空间并阻止自动为每个实例创建 __dict__
和 __weakref__
。
使用 __slots__
的注意事项:
__slots__
的类时,实例的 __dict__
和 __weakref__
属性将总是可访问的。__dict__
变量,实例就不能给未在 __slots__
定义中列出的新变量赋值。 尝试给一个未列出的变量名赋值将引发 AttributeError。 如果需要动态地给新变量赋值,则要将 __dict__
加入到在 __slots__
中声明的字符串序列中。__weakref__
变量,则定义了 __slots__
的类就不支持对其实例的 弱引用。 如果需要支持弱引用,则要将 __weakref__
加入到在 __slots__
中声明的字符串序列中。__slots__
是通过为每个变量名创建 描述器 在类层级上实现的。 因此,类属性不能被用来为通过 __slots__
定义的实例变量设置默认值;否则,类属性将会覆盖描述器赋值。__slots__
声明的作用不只限于定义它的类。 在父类中声明的 __slots__
在其子类中同样可用。 不过,子类将会获得 __dict__
和 __weakref__
除非它们也定义了 __slots__
(其中应当仅包含任何 附加 槽位的名称)。*__slots__*
则将引发 TypeError。__slots__
。__slots__
赋值,则该字典的键将被用作槽位名称。 字典的值可被用来为每个属性提供将被 inspect.getdoc() 识别并在and displayed in the output of help() 的输出中显示的文档字符串。__class__
赋值仅在两个类具有同样的 __slots__
时会起作用。__slots__
则会为该迭代器的每个值创建一个 descriptor。 但是,__slots__
属性将为一个空迭代器。更新时间:March 3, 2024, 8:58 p.m. 标签:python 特殊属性 数据成员