亲宝软件园·资讯

展开

python 魔法方法之 __ slots __的实现

go&Python 人气:0

__ slots __

__slots__是python class的一个特殊attribute,能够节省内存空间。正常情况下,一个类的属性是以字典的形式来管理, 每个类都会有__ dict__ 方法。但是我们可以通过 设置 __ slots__ 来将类的属性构造成一个静态的数据结构来管理,里面存储的是 value references。

class Bar(object):
    def __init__(self, a):
        self.a = a


class BarSlotted(object):
    __slots__ = "a",

    def __init__(self, a):
        self.a = a


# create class instance
bar = Bar(1)
bar_slotted = BarSlotted(1)

print(set(dir(bar)) - set(dir(bar_slotted)))
# {'__dict__', '__weakref__'}   
'''
使用 __slots__ 后, 类里面会减少 __dict__  __weakref__ 两个方法。
__weakref__  --- 弱引用  详情链接 https://docs.python.org/zh-cn/3/library/weakref.html
'''

优点:

缺点:

定义死后,不能去申请新的属性,申请会报属性错误

在这里插入图片描述

可以通过 把 __ dict__ 作为 __ slots__ 的一个属性,实现既能通过定义__ slots__ 节约内存,又实现新属性的定义。

class BarSlotted(object):
    __slots__ = "a",'__dict__'

    def __init__(self, a):
        self.a = a
        
bar_slotted = BarSlotted(1)
bar_slotted.b = "111"

当你事先知道class的attributes的时候,建议使用slots来节省memory以及获得更快的attribute access。

注意不应当用来限制__slots__之外的新属性作为使用__slots__的原因,可以使用装饰器以及反射的方式来实现属性控制。

注意事项

子类会继承父类的 __ slots__

class Parent(object):
    __slots__ = "x", "y"


class Child(Parent):
    __slots__ = "z",
    # 重复的 x, y 可以不写,
    # __slots__ = "x", "y", "z"


child = Child()
print(dir(child)) 
# [..., 'x', 'y', 'z']

不支持多继承, 会直接报错

class ParentA(object):
    __slots__ = "x",


class ParentB(object):
    __slots__ = "y",


class Child(ParentA, ParentB):
    pass

'''
Traceback (most recent call last):
  File "C:/Users/15284/PycharmProjects/pythonProject/test.py", line 69, in <module>
    class Child(ParentA, ParentB):
TypeError: multiple bases have instance lay-out conflict
'''

只允许父类中有一方设定了 __ slots__

class AbstractA(object):
  __slots__ = ()

class AbstractB(object):
  __slots__ = "x"

class Child(AbstractA, AbstractB):
  __slots__ = "x", "y"

新版本的 pickle中的 pickle含有slotted class,使用时需要注意

加载全部内容

相关教程
猜你喜欢
用户评论