十二. __slots__ 和 __dict__
十二. __slots__ 和 __dict__
1.__slots__
默认我们可以给class实例绑定任何属性和方法,这就是动态语言的灵活性如果我们想要限制class的属性怎么办?比如,只允许对Persion实例添加name和age属性。为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class能添加的属性
- slots是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)
class Str:
# __slots__ = "name"
# __slots__ = ["name","age"]
__slots__ = ("name","age") # 对象只拥有 name,age 属性
def __init__(self,name,age):
self.name = name
self.age = age
# self.sex = sex
p1 = Str("shawn",22)
print(p1.__slots__) # ('name', 'age')
print(p1.name,p1.age) # shawn 22
p1.friend = "水冰月" # 报错 : "AttributeError" (friend没有放到slots中)
一旦在类中使用了 slots 属性, 实例出来的对象将不会有自己的 dict, 所有的对象,都共享使用类名称空间中的属性, 在此之前每生成一个对象, 都会申请一份内存空间, 对象越多, 占用的空间就越多, 使用了slots后, 对象越多,越节省内存
- 共享类的名称空间属性示例
class Str:
__slots__ = ["name","age"]
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Str("大雄",22)
p2 = Str("静香",90)
print(p1.name,p1.age) # 大雄 22
print(p2.name,p2.age) # 静香 90
print(p1.__slots__) # ['name', 'age']
print(p2.__slots__) # ['name', 'age']
print(p1.__dict__) # 报错 : "AttributeError" 没有该属性
print(p1.__dict__) # 报错 : "AttributeError" 没有该属性
print(Str.__dict__)
'''输出
{'__module__': '__main__', '__slots__': ['name', 'age'], '__init__': <function Str.__init__ at 0x0000025344BEC828>, \
'age': <member 'age' of 'Str' objects>, 'name': <member 'name' of 'Str' objects>, '__doc__': None}
'''
- 当改变类的 name 和 age 时
Str.name = "小玉"
Str.age = 77
print(p1.name,p1.age) # 小玉 77
print(p2.name,p2.age) # 小玉 77
# 🔰发现所有对象的属性都发生了改变
总结 : 第一 : slots 属性是类属性, 可以用来限制实例对象能拥有的属性, 并且不再有自己的名称空间
第二 : 对象属性字典会占用大量内存,如果你有一个属性很少的类,但是有很多实例,为了节省内存可以使用slots取代实例的 dict
2.__dict__
- dict 在前面的许多地方都使用到了 dict 这个属性, 它用来查看一个对象或类的名称空间属性,也可以说属性字典
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
P1 = Person("夏尔凡多姆海恩",1250)
print(P1.__dict__)
# {'name': '夏尔凡多姆海恩', 'age': 1250}
print(Person.__dict__)
'''
{'__module__': '__main__', '__init__': <function Person.__init__ at 0x0000021CDDDAC4C8>, '__dict__': <attribute '__dict__' of 'Person' objects>,\
'__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
'''

浙公网安备 33010602011771号