如果我们想要限制类对象的属性,比如我们只允许让类的对象只能有某几个属性有效,可以定义一个特殊的变量
__slots__ 来限制,要注意 __slots__ 的值必须是可迭代的(str,list,tuple,set,dict
或者自定义可迭代对象),但是我们一般习惯于使用一个元组
来表示。
我们定义一个 Human 类,让该类定义的对象只有一个 sex 属性,其它属性无效。
class Human(object): __slots__ = ("sex",) def __init__(self): self.sex = "女" self.age = 18 # 错误,不允许除 sex 以外的属性存在 ruhua = Human() # 定义此语句,调用构造函数执行代码
当然,给对象动态添加属性也受 __slots__ 限制。下面我们不在举动态增加属性的例子,大家可以自行试验。
class Human(object): __slots__ = ("sex",) def __init__(self): self.sex = "女" ruhua = Human() # 定义此语句,调用构造函数执行代码 ruhua.age = 18 # 错误,不允许除 sex 以外的属性存在
要注意 __slots__ 无法限制类的属性。
class Human(object): __slots__ = ("sex",) age = 18 # 正确,age 是属于类的,__slots__ 无法限制类属性 def __init__(self): self.sex = "女" ruhua = Human() print(ruhua.age)
在有继承关系的类中,如果只有基类中有 __slots__,子类中没有 __slots__,要注意基类中 __slots__ 定义的属性仅对当前类的对象起限制作用,对继承的子类的对象不起作用。
class Human(object): __slots__ = ("sex",) def __init__(self): self.sex = "女" self.name = "human" # 错误,受 __slots__ 限制 class Woman(Human): def __init__(self): Human.__init__(self) self.age = 18 # 正确,不受基类的 __slots__ 限制 hm = Human() # hm 是基类对象 ruhua = Woman() # ruhua 是子类对象
如果想让定义的 __slots__ 在子类中也起作用,需要在子类中也定义 __slots__, 这样以来子类的对象允许定义的属性就被限制于自身的 __slots__ 加上父类的 __slots__。
class Human(object): __slots__ = ("sex",) def __init__(self): self.sex = "女" # 正确,只受 Human 类中的 __slots__ 限制 self.name = "如花" # 错误,只受 Human 类中的 __slots__ 限制 class Woman(Human): __slots__ = ("name",) def __init__(self): self.sex = "女" # 正确,符合基类中的 __slots__ 限制 self.name = "如花" # 正确,符合子类中的 __slots__ 限制 self.age = 18 # 错误,不符合基类和子类中的 __slots__ 限制 ruhua = Woman()
注意:如果只有子类中有 __slots__,而基类中没有定义 __slots__,则子类中的 __slots__对 子类的对象或基类中的对象都不起任何作用。
class Human(object): def __init__(self): self.sex = "女" # 正确,子类中的 __slots__ 不起任何作用 self.name = "如花" # 正确,子类中的 __slots__ 不起任何作用 class Woman(Human): __slots__ = ("name",) def __init__(self): self.sex = "女" # 正确,子类中的 __slots__ 不起任何作用 self.name = "如花" # 正确,子类中的 __slots__ 不起任何作用 self.age = 18 # 正确,子类中的 __slots__ 不起任何作用 ruhua = Woman()
要知道 __slots__ 只能对对象进行属性限制,而无法对类本身进行属性限制。
要知道 __slots__ 在有继承关系的类中对子类对象属性的限制规则。
在有 __slots__ 限制的类中,给类动态增加属性可以不受限制,给类的对象动态增加属性而会受到限制,为什么。
class Human(object): __slots__ = ("sex",) def __init__(self): self.sex = "女" ruhua = Human() ruhua.age = 18 # 错误 Human.age = 18 # 正确
slots 是语法糖啊,我一般不用