对于用户定义的类(使用
class常规Python代码中的关键字定义),一个类将始终
__slots__在该类,
__dict__该实例上或同时在这两个类上(如果定义的插槽
'__dict__'之一是,或在继承链中是用户定义的类之一)定义
__slots__而另一个则没有,
__dict__隐式创建)。因此,这是用户定义的类涵盖的四种可能性中的三种。
编辑: 一项更正:从技术上讲,用户定义的类可能都
没有
;该类将使用进行定义
__slots__,但是在定义后将其删除(设置类型的机制不需要
__slots__在类定义完成后保留下来)。没有理智的人应该这样做,它可能会带来不良的副作用(未经测试的完整行为),但是有可能。
对于内置类型,至少在CPython参考解释器中,它们 极 不可能具有
__slots__(如果这样做的话,那将是模拟用户定义的类,定义它实际上
没有
任何用处)。内置类型通常将其属性作为原始C级值和指针存储在C级结构上,还可以选择使用显式创建的描述符或访问器方法来存储,这消除了的目的
__slots__,而这仅仅是此类结构游戏的一种方便的有限用途等效项用户定义的类。
__dict__是针对内置类型选择启用的,默认情况下不启用(尽管选择过程相当简单;您需要
PyObject*在结构中的某处放置一个条目,并在类型定义中为其提供偏移量)。
需要明确的是,
__dict__不必出现在 类上 就可以使其出现在其 实例上 ;
__slots__是类级别的,并且可以抑制
实例
__dict__上的,但对类本身是否具有;没有影响;用户定义的 类 始终具有,但是如果您谨慎使用它们的实例将不会。
__dict__
__dict__``__slots__
简而言之:
(合理)用户定义的类至少具有
__dict__(在实例上)或
__slots__(在类上)之一,并且可以同时具有两者。疯狂的用户定义类 可能
根本没有,但是只有一个杂乱无章的开发人员才能做到。
内置类通常都不提供, 可能 提供
__dict__,并且几乎从不提供,
__slots__因为对他们而言毫无意义。
例子:
# Class has __slots__, instances don't have __dict__class DictLess: __slots__ = ()# Instances have __dict__, class lacks __slots__class DictOnly: pass# Class has __slots__, instances have __dict__ because __slots__ declares itclass SlottedDict: __slots__ = '__dict__',# Class has __slots__ without __dict__ slot, instances have it anyway from unslotted parentclass DictFromParent(DictOnly): __slots__ = ()# Complete insanity: __slots__ takes effect at class definition time, but can# be deleted later, without changing the class behavior:class NoSlotNoDict: __slots__ = ()del NoSlotNoDict.__slots__# Instances have no __dict__, class has no __slots__ but acts like it does# (the machinery to make it slotted isn't undone by deleting __slots__)# Please, please don't actually do this# Built-in type without instance __dict__ or class defined __slots__:int().__dict__ # Raises AttributeErrorint.__slots__ # Also raises AttributeError# Built-in type that opts in to __dict__ on instances:import functoolsfunctools.partial(int).__dict__ # Works finefunctools.partial.__slots__ # Raises AttributeError



