一、__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("吉吉",8) print(P1.__slots__) #('name', 'age') print(P1.name,P1.age) #吉吉 8 P1.frind="淘小欣" # 报错 : "AttributeError" (friend没有放到slots中)
一旦在类中使用了 slots 属性, 实例出来的对象将不会有自己的 dict, 所有的对象,都共享使用类名称空间中的属性, 在此之前每生成一个对象, 都会申请一份内存空间, 对象越多, 占用的空间就越多, 使用了slots后, 对象越多,越节省内存
-
共享类的名称空间属性示例
class Str: __slots__ = ["name", "age"] def __init__(self, name, age): self.name = name self.age = age P1 = Str("屁屁", 9) P2 = Str("皮皮", 8) print(P1.name, P1.age) # 屁屁 9 print(P2.name, P2.age) # 皮皮 8 print(P1.__slots__) # ['name', 'age'] print(P2.__slots__) # ['name', 'age'] print(P1.__dict__) # 报错 : "AttributeError" 没有该属性 print(P2.__dict__) # 报错 : "AttributeError" 没有该属性 print(Str.__dict__) '''输出内容 {'__module__': '__main__', '__slots__': ['name', 'age'], '__init__': <function Str.__init__ at 0x000001AB93F6F040>, '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 属性是类属性, 可以用来限制实例对象能拥有的属性, 并且不再有自己的名称空间
第二 : 对象属性字典会占
二、__dict__
-
dict 在前面的许多地方都使用到了 dict 这个属性, 它用来查看一个对象或类的名称空间属性,也可以说属性字典
class Person: def __init__(self,name,age): self.name=name self.age=age P1=Person("淘小欣的开发之路",3342) print(P1.__dict__) #{'name': '淘小欣的开发之路', 'age': 3342} print(Person.__dict__) '''输出内容 {'__module__': '__main__', '__init__': <function Person.__init__ at 0x0000025C92CBB4C0>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None} '''