`__slots__ 和 __dict__`

__slots__ 和 __dict__

一、__slots__

默认我们可以给class实例绑定任何属性和方法,这就是动态语言的灵活性如果我们想要限制class的属性怎么办?比如,只允许对Persion实例添加nameage属性。为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class能添加的属性

  • slots是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)

    class Str:
        # __slots__ = "name"
        # __slots__ = ["name","age"]
        __slots__ = ("name","age")  # 对象只拥有 name,age 属性
        def __init__(self,name,age):
            self.name=name
            self.age=age
            # self.sex = sex
    
    P1=Str("吉吉",8)
    print(P1.__slots__) #('name', 'age')
    print(P1.name,P1.age)   #吉吉 8
    
    P1.frind="淘小欣"      # 报错 : "AttributeError" (friend没有放到slots中)
    
    

一旦在类中使用了 slots 属性, 实例出来的对象将不会有自己的 dict, 所有的对象,都共享使用类名称空间中的属性, 在此之前每生成一个对象, 都会申请一份内存空间, 对象越多, 占用的空间就越多, 使用了slots后, 对象越多,越节省内存

  • 共享类的名称空间属性示例

    class Str:
        __slots__ = ["name", "age"]
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    
    P1 = Str("屁屁", 9)
    P2 = Str("皮皮", 8)
    print(P1.name, P1.age)  # 屁屁 9
    print(P2.name, P2.age)  # 皮皮 8
    
    print(P1.__slots__)  # ['name', 'age']
    print(P2.__slots__)  # ['name', 'age']
    
    print(P1.__dict__)     # 报错 : "AttributeError" 没有该属性
    print(P2.__dict__)     # 报错 : "AttributeError" 没有该属性
    
    print(Str.__dict__)
    '''输出内容
    {'__module__': '__main__', '__slots__': ['name', 'age'], '__init__': <function Str.__init__ at 0x000001AB93F6F040>, 'age': <member 'age' of 'Str' objects>, 'name': <member 'name' of 'Str' objects>, '__doc__': None}
    '''
    
    
  • 当改变类的 name 和 age 时

    Str.name = "小玉"
    Str.age = 77
    
    print(P1.name,P1.age)  # 小玉 77
    print(P2.name,P2.age)  # 小玉 77
    # 发现所有对象的属性都发生了改变
    

    总结 : 第一 : slots 属性是类属性, 可以用来限制实例对象能拥有的属性, 并且不再有自己的名称空间

    第二 : 对象属性字典会占

二、__dict__

  • dict 在前面的许多地方都使用到了 dict 这个属性, 它用来查看一个对象或类的名称空间属性,也可以说属性字典

    class Person:
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
    P1=Person("淘小欣的开发之路",3342)
    print(P1.__dict__)      #{'name': '淘小欣的开发之路', 'age': 3342}
    
    print(Person.__dict__)
    
    '''输出内容
    {'__module__': '__main__', '__init__': <function Person.__init__ at 0x0000025C92CBB4C0>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    '''
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贾维斯Echo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值