《老鸟python 系列》视频上线了,全网稀缺资源,涵盖python人工智能教程,爬虫教程,web教程,数据分析教程以及界面库和服务器教程,以及各个方向的主流实用项目,手把手带你从零开始进阶高手之路!点击 链接 查看详情




使用__slots__

阅读:227568123    分享到

如果我们想要限制类对象的属性,比如我们只允许让类的对象只能有某几个属性有效,可以定义一个特殊的变量 __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__ 在有继承关系的类中对子类对象属性的限制规则。

作业

在有 __slots__ 限制的类中,给类动态增加属性可以不受限制,给类的对象动态增加属性而会受到限制,为什么。

class Human(object):
    __slots__ = ("sex",)
    def __init__(self):
        self.sex = "女"

ruhua = Human()
ruhua.age = 18  # 错误
Human.age = 18  # 正确

如果以上内容对您有帮助,请老板用微信扫一下赞赏码,赞赏后加微信号 birdpython 领取免费视频。


登录后评论

user_image
Guaidaodl
2020年2月26日 12:31 回复

slots 是语法糖啊,我一般不用


user_image
老湿情报员
2020年1月15日 14:46 回复

作业:因为 __slots__ 限制的是对象


user_image
白虎保护我
2019年12月13日 07:56 回复

会有副作用吗


user_image
萃九时凝
2019年7月27日 01:04 回复

今天也看到这,看来用到的概率不大啊。