__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使用的目的
__slots__是 节省内存 ;
.__dict__该类没有在实例上使用映射,而是为每个在中命名的属性都有描述符对象,
__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().spamTraceback (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'>因此,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'
插槽描述符是在创建类时创建的,并访问分配给每个实例的内存,以存储和检索对关联值的引用(跟踪实例引用计数和对类对象的引用的同一块内存)。如果没有插槽,
__dict__则使用的描述符以
dict相同的方式访问对对象的引用。



