Cas*_*ash 14 python slots python-internals
我听说__slots__通过避免字典查找使对象更快.我的困惑来自于Python是一种动态语言.在静态语言中,我们a.test通过执行编译时优化来避免字典查找,以便在我们运行的指令中保存索引.
现在,在Python中,a可以很容易地成为另一个具有字典或不同属性集的对象.看起来我们仍然需要进行字典查找 - 唯一的区别似乎是我们只需要一个类的字典,而不是每个对象的字典.
有了这个理性,
__slots__避免字典查找?Mar*_*ers 17
__slots__ 没有(显着)加速属性访问:
>>> class Foo(object):
... __slots__ = ('spam',)
... def __init__(self):
... self.spam = 'eggs'
...
>>> class Bar(object):
... def __init__(self):
... self.spam = 'eggs'
...
>>> import timeit
>>> timeit.timeit('t.spam', 'from __main__ import Foo; t=Foo()')
0.07030296325683594
>>> timeit.timeit('t.spam', 'from __main__ import Bar; t=Bar()')
0.07646608352661133
Run Code Online (Sandbox Code Playgroud)
使用的目的__slots__是节省内存 ; 而不是.__dict__在实例上使用映射,该类具有名称为in的每个属性的描述符对象,__slots__并且实例具有已分配的属性,是否具有实际值:
>>> class Foo(object):
... __slots__ = ('spam',)
...
>>> dir(Foo())
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'spam']
>>> Foo().spam
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: spam
>>> Foo.spam
<member 'spam' of 'Foo' objects>
>>> type(Foo.spam)
<type 'member_descriptor'>
Run Code Online (Sandbox Code Playgroud)
因此,python仍然必须查看类的实例上的每个属性访问Foo(以查找描述符).任何未知的属性(比如说Foo.ham)都会导致Python通过类MRO查找该属性,其中包括字典搜索.您仍然可以为该类分配其他属性:
>>> Foo.ham = 'eggs'
>>> dir(Foo)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'ham', 'spam']
>>> Foo().ham
'eggs'
Run Code Online (Sandbox Code Playgroud)
创建类时创建槽描述符,并为每个实例分配访问内存以存储和检索对相关值的引用(跟踪实例引用计数的同一块内存和返回类对象的引用).没有插槽,描述符用于__dict__以dict相同的方式访问对象的引用.
| 归档时间: |
|
| 查看次数: |
3499 次 |
| 最近记录: |