写点什么

Python3 Note __slots__

用户头像
awen
关注
发布于: 2021 年 06 月 01 日

slots

__slots__是 python 对象的一个特殊属性。

示例

    class FooSlot(object):        __slots__ = "a",            def __init__(self, a):            self.a = a        foo = Foo(1)    print(dir(foo))    foo_slot = FooSlot(1)    print(dir(foo_slot))    print(foo.__dict__)    print(foo_slot.__slots__)
复制代码

结果如下:

    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a']    ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'a']    {'a': 1}    ('a',)
复制代码


通过观察发现: foo 对象的属性比 foo_slot 多了一个__dict__和__weakref__,少了一个__slots__ foo.__dict__的值为{'a': 1},foo_slot.__slots__的值为('a',)

__slots__的两大好处

  • 节省内存占用 Python 内置的__dict__本质是一个哈希表,是一种用空间换时间的数据结构。为了解决冲突的问题,当字典使用量超过 2/3 时,Python 会根据情况进行 2-4 倍的扩容。由此可预见,取消__dict__的使用可以大幅减少实例的空间消耗。


    from pympler import asizeof    print(asizeof.asizeof(foo)) #256    print(asizeof.asizeof(foo_slot)) #80
复制代码


  • 加快访问速度默认情况下,访问 Python 对象的属性,需要 1)访问对象 foo.a 2)foo.dict 即(get & set) 3)foo.dict['a'] 4)结果。当使用了__slots__以后,直接访问 1) foo_slots.a 2) member_descriptor 即(get & set) 3)结果



def test_speed_fn(obj): def test_speed(): obj.a = 1 obj.a del obj.a return test_speed from timeit import repeat ta = min(repeat(test_speed_fn(foo))) tb = min(repeat(test_speed_fn(foo_slot))) print("%.2f%%" % ((ta/tb - 1)*100)) #28.19%
复制代码


用户头像

awen

关注

Things happen for a reason. 2019.11.15 加入

还未添加个人简介

评论

发布
暂无评论
Python3 Note __slots__