1. 简介
Python中的__slots__
是一种类属性,可用于控制类的属性和方法的命名空间,以减少内存使用和提高程序运行效率。
2. __slots__的基础使用
2.1 定义一个类
定义一个简单的类来演示__slots__
的基础使用。在这个类中,我们使用一个字典__dict__
来存储属性:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
这样就可以进行属性的赋值和使用:
p = Person('Tom', 20)
print(p.name)
print(p.age)
输出结果:
Tom
20
2.2 添加__slots__属性
在上面的代码中,每个实例对象都会创建一个__dict__
字典来存储属性,这会占用一定的内存。如果我们想要减少内存的使用,则可以使用__slots__
属性。
这是一个例子,我们只需要将__slots__
属性设置为一个元组,里面包含所有的属性名:
class Person:
__slots__ = ('name', 'age')
def __init__(self, name, age):
self.name = name
self.age = age
这样就可以减少对象内存的使用,因为每个实例对象只会分配一个固定大小的数组来存储属性值。由于__slots__
告诉Python只分配那些列在其中的属性,它将消除实例字典和调整实例的存储,从而提高程序运行效率。
2.3 使用__slots__属性
现在,我们再次创建一个对象并使用它:
p = Person('Tom', 20)
print(p.name)
print(p.age)
输出结果:
Tom
20
如果我们试图访问此对象的其他属性,Python将会引发一个AttributeError, 因为它们没有被列在__slots__
属性中:
p.gender = 'male'
输出结果:
AttributeError: 'Person' object has no attribute 'gender'
3. __slots__的高级用法
3.1 使用基类的__slots__
我们可以在类中指定__slots__
属性,也可以在基类中指定。如果在基类中指定了__slots__
属性,则在派生类中也可以使用这些属性。
这是一个例子:
class A:
__slots__ = ('a',)
class B(A):
__slots__ = ('b',)
class C(B):
__slots__ = ('c',)
在这个例子中,类C
将会有3个属性a
,b
和c
。由于__slots__
是继承的,所以B
类继承了A
类的__slots__
属性,C
类继承了B
类和A
类的__slots__
属性。
3.2 在__slots__中添加方法
我们可以在__slots__
属性中指定方法,就像指定其他属性一样。不过,需要注意的一点是,这些方法将变成静态方法,不会像普通方法那样接收一个隐含的self参数。
这个例子演示了如何在__slots__
中指定方法:
class Person:
__slots__ = ('name', 'age', 'get_name')
def __init__(self, name, age):
self.name = name
self.age = age
def get_name(self):
return self.name
现在,get_name()
方法成为了这个类的一个属性,可以像其他属性一样访问。不过,我们需要注意到,此时这个方法变成了一个静态方法,不能像普通方法那样接收一个隐含的self参数,因为__slots__
只是一个属性列表,Python不能自动将self参数分配到一个固定的槽位上。
3.3 使用__dict__和__weakref__属性
使用__slots__
属性后,类实例不再具有__dict__
属性来存储实例的属性字典,也不再具有__weakref__
属性用来支持垃圾回收。如果需要这些特性,可以将它们包含在__slots__
元组中。
这是一个例子:
class Person:
__slots__ = ('name', 'age', '__dict__', '__weakref__')
def __init__(self, name, age):
self.name = name
self.age = age
现在,实例对象具有__dict__
和__weakref__
属性,请注意,它们也可以作为__slots__
元组的一部分,就像其他属性一样。
4. 总结
Python __slots__的使用方法:
通过使用__slots__
属性,可以减少内存使用和提高程序运行效率。我们可以在__slots__
中指定属性和方法,并可以在继承中使用。__slots__
属性还可以包括__dict__
和__weakref__
属性,以支持类的字典和垃圾回收。静态方法也可以指定为__slots__
属性的一部分。