python 魔法方法之 __ slots __的实现
__ 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__
的内存,__ weakref__
也不用去申请 - access attributes 更快,静态数据结构,比
__ dict__
更快
缺点:
定义死后,不能去申请新的属性,申请会报属性错误
可以通过 把 __ 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,使用时需要注意
到此这篇关于python 魔法方法之 __ slots __的实现的文章就介绍到这了,更多相关python __ slots __内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
相关文章