python类的__slots__方法

由于Python是动态语言,任何实例在运行期都可以动态地添加属性。比如:

class Student(object):
    def __init__(self, name, gender, score):
        self.name = name
        self.gender = gender
        self.score = score

此时,Student类有三个属性,name、gender、score,由于是动态语言,在运行时,可以随意添加属性。

student = Student('Bob', 'Male', 99)
student.age = 12 # ==> 动态添加年龄age属性

如果要限制添加的属性,例如,Student类只允许添加 name、gender和score 这3个属性,就可以利用Python的一个特殊的__slots__来实现。

class Student(object):
    __slots__ = ('name', 'gender', 'score')
    def __init__(self, name, gender, score):
        self.name = name
        self.gender = gender
        self.score = score

使用__slots__ = ('name', 'gender', 'score') 限定Student类的属性,这个时候在外部再次添加动态属性age,将会报错。

>>> student = Student('Bob', 'Male', 99)
>>> student.age = 12 # ==> 动态添加年龄age属性
Traceback (most recent call last):
AttributeError: 'Student' object has no attribute 'age'

__slots__的目的是限制当前类所能拥有的属性,避免因为外部属性的操作导致类属性越来越难以管理。

import types
class Person(object):
    __slots__ = ("name", "age")  # 定义__slots__    
    def __init__(self, newName, newAge):
        self.name = newName
        self.age = newAge

    def eat(self):
        print("---正在吃---")

def run(self):
    print("---正在跑---")

Person.num = 100        # 类Person动态添加类属性num

zhangsan = Person("张三", 18)
print(zhangsan.name)    # 张三
print(zhangsan.age)     # 18
print(zhangsan.num)     # 100
zhangsan.eat()          # ---正在吃---

zhangsan.addr = "北京"   # 'Person' object has no attribute 'addr'
zhangsan.run = types.MethodType(run, zhangsan)  # 'Person' object has no attribute 'run'

通过以上代码可知,__slots__对Person类的动态添加没有限制,而Person类对象zhangsan不能再动态添加对象属性和方法。

对于__slot__有以下几个需要注意的地方:

  • __slots__只对类对象进行限制,不对类进行限制
  • __slots__不仅限制类对象的属性,还限制类对象的方法
  • __slots__仅对当前类起作用,对继承的子类不起作用
  • 在子类中定义__slots__,子类允许定义的属性就是自身的__slots__加上父类的__slots__
原文地址:https://www.cnblogs.com/fat-girl-spring/p/15007702.html