__slots__

前言

  • 我们在使用类的时候,常规做法是会先实例化一个该类的对象,然后可以为此实例对象动态的添加实例方法或者实例属性
  • __slots__属性就相当于是一个白名单,只有在白名单中才可以添加

需要注意

  • 对于类,Python允许为类动态地添加这三种方法(实例方法、静态方法和类方法)
  • 对于实例对象,则Python只允许动态地添加实例方法,不能添加类方法和静态方法
  • 为单个实例对象添加方法,不会影响该类的其它实例对象
  • 为类动态地添加方法或更改,则会影响所有的实例对象。

__ slots__

__ slots__ 只能限制为实例对象动态添加属性和方法,而无法限制动态地为类添加属性和方法。

    class Slots:         __slots__ = (name, info)          def test(self):             print(This is Test)      def info(self, name):         print(正在调用实例方法, self.name)      slots = Slots()     slots.test()     slots.name = 'Jim'     print(slots.name)     slots.info = info     slots.info(slots, Tom)     slots.age = 15     print(slots.age) 

运行结果:

This is Test Jim 正在调用实例方法 Jim Traceback (most recent call last):   File tests.py, line 101, in <module>     slots.age = 15 AttributeError: 'Slots' object has no attribute 'age' 

另外,__ slots__ 属性限制的对象是类的实例对象,而不是类,因此下面的代码是合法的:

Slots.age = 15 print(Slots.age) 运行结果: 15 

作用域

此外,__ slots__ 属性对由该类派生出来的子类,是不起作用的。例如如下代码:

class CLanguage:     __slots__ = ('name','add','info') #Clanguage 的空子类 class CLangs(CLanguage):     pass #定义的实例方法 def info(self):     print(正在调用实例方法) clang = CLangs() #为子类对象动态添加 say() 方法 clang.say = info clang.say(clang)  ### 运行结果: 正在调用实例方法 

总结

所以,__ slots__ 属性只对当前所在的类起限制作用。
此外,如果子类也要限制外界为其实例对象动态地添加属性和方法,必须在子类中设置 __ slots__ 属性。那么子类实例对象允许动态添加的属性和方法,是子类中 __ slots__ 属性和父类 __ slots__ 属性的和。