__slots__
允许我们声明并限定类成员,并拒绝类创建__dict__
和__weakref__
属性以节约内存空间。
Python是动态语言,对于普通的类,可以为类实例赋值任何属性,这些属性会存储在__dict__
中:
class Persion(object):
pass
p=Persion()
p.name='leizi'
print(p.__dict__)
结果展示
代码语言:javascript复制{'name': 'leizi'}
这样的特性带来两个问题:
- 数据通过字典(Hash)存储所占用的空间较大
- 如何禁止随意生成类属性
当然,__slots__
就能解决这两个问题。通过__slots__
属性限定类属性的创建:
class Persion(object):
__slots__ = ['name','age']
pass
p=Persion()
p.name='leizi'
p.phone=123
print(p.__dict__)
结果
代码语言:javascript复制 p.phone=123
AttributeError: 'Persion' object has no attribute 'phone'
可以看到,在定义了__slots__变量后,Student类实例已经不能随意创建不在__slots__定义内的属性phone,同时实例中也不再有__dict__结构。
使用:
__slots__在继承中有两种表现:
- 子类未声明__slots__时,不继承父类的__slots__,即此时子类实例可以随意赋值属性
- 子类声明__slots__时,继承父类的__slots__,即此时子类的__slots__为其自身 父类的__slots__
class Persion(object):
__slots__ = ['name','age']
pass
class newPerson(Persion):
pass
a=newPerson()
a.name=122
a.city="shanghao"
print(a.__dict__)
结果:
子类没有继承,这样就是没有继承父类的,可以随意的赋值。
代码语言:javascript复制class Persion(object):
__slots__ = ['name','age']
pass
class newPerson(Persion):
__slots__ = ("like")
pass
a=newPerson()
a.name=122
a.like='say '
a.city="shanghao"
结果:
代码语言:javascript复制 a.city="shanghao"
AttributeError: 'newPerson' object has no attribute 'city'
子类继承了父类的,并且定义了自己的,这样只能使用限定的。那么没有定义的city不能赋值。