示例:# 类有__slots__,实例没有__dict__DictLess 类:__slots__ = ()# 实例有 __dict__,类没有 __slots__DictOnly 类:经过# 类有 __slots__,实例有 __dict__ 因为 __slots__ 声明了它类 SlottedDict:__slots__ = '__dict__',# 类有 __slots__ 没有 __dict__ 槽,实例有它来自未槽的父类 DictFromParent(DictOnly):__slots__ = ()# 完全疯了:__slots__ 在类定义时生效,但是可以# 稍后删除,不改变类行为:NoSlotNoDict 类:__slots__ = ()del NoSlotNoDict.__slots__# 实例没有 __dict__,类没有 __slots__ 但行为就像它一样#(通过删除 __slots__ 并不能撤消使其开槽的机制)#拜托,请不要真的这样做# 没有实例 __dict__ 或类定义的 __slots__ 的内置类型:int().__dict__ # 引发 AttributeErrorint.__slots__ # 也会引发 AttributeError# 在实例上选择 __dict__ 的内置类型:导入功能工具functools.partial(int).__dict__ # 工作正常functools.partial.__slots__ # 引发 AttributeErrorFrom https://stackoverflow.com/a/1529099/156458If an object doesn't have __dict__, does its class must have a __slots__ attribute?For example an instance of object doesn't have __dict__, >>> object().__dict__Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'object' object has no attribute '__dict__'but>>> object.__slots__Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: type object 'object' has no attribute '__slots__'So why does an instance of object not have __dict__ and object has no __slots__ attribute?Does an instance of object have any attribute?How many possibilities are there:an object has __dict__, and its class has __dict__ but no __slots__an object doesn't have __dict__, and its class has __slots__an object doesn't have __dict__, and its class doesn't have __slots__ ?Is it possible to tell if an object has __dict__ from its class?if its class has __slots__, then it doesn't have __dict__if its class doesn't have __slots__, how can I tell if it has __dict__ or not? 解决方案 For user defined classes (defined using the class keyword in regular Python code), a class will always have __slots__ on the class, __dict__ on the instance, or both (if one of the slots defined is '__dict__', or one of the user defined classes in an inheritance chain defines __slots__ and another one does not, creating __dict__ implicitly). So that's three of four possibilities covered for user defined classes.Edit: A correction: Technically, a user-defined class could have neither; the class would be defined with __slots__, but have it deleted after definition time (the machinery that sets up the type doesn't require __slots__ to persist after the class definition finishes). No sane person should do this, and it could have undesirable side-effects (full behavior untested), but it's possible.For built-in types, at least in the CPython reference interpreter, they're extremely unlikely to have __slots__ (if they did, it would be to simulate a user-defined class, defining it doesn't actually do anything useful). A built-in type typically stores its attributes as raw C level values and pointers on a C level struct, optionally with explicitly created descriptors or accessor methods, which eliminates the purpose of __slots__, which are just a convenient limited purpose equivalent of such struct games for user defined classes. __dict__ is opt-in for built-in types, not on by default (though the opt-in process is fairly easy; you need to put a PyObject* entry somewhere in the struct and provide the offset to it in the type definition).To be clear, __dict__ need not appear on the class for it to appear on its instances; __slots__ is class level, and can suppress the __dict__ on the instance, but has no effect on whether the class itself has a __dict__; user defined classes always have __dict__, but their instances won't if you're careful to use __slots__ appropriately.So in short:(Sane) User defined classes have at least one of __dict__ (on the instances) or __slots__ (on the class), and can have both. Insane user defined classes could have neither, but only a deranged developer would do it.Built-in classes often have neither, may provide __dict__, and almost never provide __slots__ as it is pointless for them.Examples:# 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 这篇关于如果一个对象没有 `__dict__`,它的类是否必须有一个 `__slots__` 属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-28 17:03