美文网首页
__slots__节省内存空间

__slots__节省内存空间

作者: MononokeHime | 来源:发表于2018-07-04 14:08 被阅读0次

    动态语言:可以在运行的过程中,修改代码

    静态语言:编译时已经确定好代码,运行过程中不能修改

    如果我们想要限制实例的属性怎么办?比如,只允许对Person实例添加name和age属性。

    为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性。注意:使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

    __slots__的作用:

    • 指明对象可以绑定的属性,限制对象任意绑定属性
    • 节省内存空间,每个对象都有__dict__属性,该字典存放着属性与值的映射关系。使用slots可以省去这个字典

    1.绑定属性

    class Foo(object):
        __slots__ = ("name", "age")
    
        def __init__(self):
            self.name = 'book'
            self.age = 18
            self.email = 'abc@qq.com'
    
    foo = Foo()
    

    输出

    Traceback (most recent call last):
      File "/Users/Liang/Documents/PyProject/demo1.py", line 11, in <module>
        foo = Foo()
      File "/Users/Liang/Documents/PyProject/demo1.py", line 7, in __init__
        self.email = 'abc@qq.com'
    AttributeError: 'Foo' object has no attribute 'email'
    

    2.节省内存

    在默认情况下,Python的新类和旧类的实例都有一个字典__dict__来存储属性值。这对于那些没有实例属性的对象来说太浪费空间了,当需要创建大量实例的时候,这个问题变得尤为突出(Python内置的字典本质是一个哈希表,它是一种用空间换时间的数据结构。为了解决冲突的问题,当字典使用量超过2/3时,Python会根据情况进行2-4倍的扩容。由此可预见,取消__dict__的使用可以大幅减少实例的空间消耗。)。因此这种默认的做法可以通过在新式类中定义了一个__slots__属性从而得到了解决。__slots__声明中包含若干实例变量,并为每个实例预留恰好足够的空间来保存每个变量,因此没有为每个实例都创建一个字典,从而节省空间。以下是用元祖来存储实例属性,这样Python会在实例中使用类似元祖的结构存储实例变量。

    class Foo1(object):
        __slots__ = ("name", "age")  # 也可以用列表存储
    
        def __init__(self):
            self.name = 'book'
            self.age = 18
    
    class Foo2(object):
    
        def __init__(self):
            self.name = 'book'
            self.age = 18
    
    foo1 = Foo1()
    foo2 = Foo2()
    print(dir(foo1))  # 没有__dict__属性
    print(dir(foo2))
    

    3.slots的副作用

    1. 每个继承的子类都要重新定义一遍__slots__
    2. 实例只能包含哪些在__slots__定义的属性,这对写程序的灵活性有影响,比如你由于某个原因新网给instance设置一个新的属性,比如instance.a = 1, 但是由于a不在__slots__里面就直接报错了,你得不断地去修改__slots__或者用其他方法迂回的解决
    3. 实例不能有弱引用(weakref)目标,否则要记得把__weakref__放进__slots__

    相关文章

      网友评论

          本文标题:__slots__节省内存空间

          本文链接:https://www.haomeiwen.com/subject/bnyeuftx.html