Python中__slots__的使用

admin 阅读:51 2024-02-29

如果我们想要限制类对象的属性,比如我们只允许让类的对象只能有某几个属性有效,可以定义一个特殊的变量 __slots__ 来限制,要注意 __slots__ 的值必须是可迭代的(str,list,tuple,set,dict 或者自定义可迭代对象),但是我们一般习惯于使用一个元组来表示。

使用 __slots__

我们定义一个 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__ 在有继承关系的类中对子类对象属性的限制规则。

声明

1、部分文章来源于网络,仅作为参考。
2、如果网站中图片和文字侵犯了您的版权,请联系1943759704@qq.com处理!