当前位置: 首页 > 面试题库 >

如果对象不具有__dict__,则其类是否必须具有__slots__属性?

松钊
2023-03-14
问题内容

从https://stackoverflow.com/a/1529099/156458

为了支持任意属性分配,对象需要一个__dict__:与对象关联的字典,可以在其中存储任意属性。否则,就无处放置新属性。

在可怕的循环依赖问题之前(因为它像大多数其他事物一样,都是从;-继承的),它的实例object不会携带__dict__-如果这样做的话,这会使python中的每个对象都受字典约束,这意味着开销当前没有或不需要字典的每个对象中有多少字节(基本上,所有不具有任意可分配属性的对象都没有或不需要字典)。__dict__``object

当类具有__slots__特殊属性(字符串序列),那么class语句(更准确地说,默认元类type)并 没有
装备该类的每个实例有一个__dict__(有任意属性,因此的能力),只是一个有限,一组具有给定名称的刚性“槽”(基本上是每个可以容纳对某个对象的引用的位置)。

如果对象不具有__dict__,则其类是否必须具有__slots__属性?

例如,的实例object没有__dict__

>>> object().__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute '__dict__'

>>> object.__slots__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'object' has no attribute '__slots__'

那么,为什么一个实例object没有__dict__object有没有 __slots__属性?

的实例object具有任何属性吗?

有多少种可能性:

  • 一个对象具有__dict__,其类具有__dict__但没有__slots__
  • 对象不具有__dict__,其类具有__slots__
  • 一个对象没有__dict__,它的类也没有__slots__

是否可以判断某个对象是否__dict__来自其类?

  • 如果其类具有__slots__,则它不具有__dict__
  • 如果它的班级没有__slots__,我怎么知道它有__dict__没有?

问题答案:

对于用户定义的类(使用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 it
class SlottedDict:
    __slots__ = '__dict__',

# Class has __slots__ without __dict__ slot, instances have it anyway from unslotted parent
class 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 AttributeError
int.__slots__   # Also raises AttributeError

# Built-in type that opts in to __dict__ on instances:
import functools
functools.partial(int).__dict__ # Works fine
functools.partial.__slots__ # Raises AttributeError


 类似资料:
  • 这里有几个关于如何检查对象中是否存在属性的答案。 我一直在使用 但我想知道这和

  • 问题内容: Python中是否有一种方法可以确定对象是否具有某些属性?例如: 在使用a属性property之前,如何知道该属性是否存在? 问题答案: 尝试: 编辑:请参阅下面的的答案,他为寻求宽恕提供了很好的建议!一个非常的方法! 中的一般做法是,如果大多数情况下该属性很可能存在,则只需对其进行调用,然后让该异常传播,或者使用块将其捕获。这可能会比快。如果该属性在大多数时间可能不存在,或者你不确定

  • 问题内容: 我不想拥有hibernate.cfg.xml文件。而是我想通过我的代码进行所有配置,如下所示。 我已经尝试了上述方法。但是我面临的问题是hibernate抛出一个异常,说“ ”。 保留文件真的是强制性的吗? 提前致谢 问题答案: 我相信这是由于您对对象的调用。尝试删除该文件,hibernate状态将不会查找不存在的文件。基本上,您是通过对象设置所有必需的属性,因此并不需要告诉Hiber

  • 我想建立一个本体模型,在那里我可以表示一个实体的缺失,可以这么说。例如,我希望有Rain和No_Rain,我将它们定义为不相交类。在此之后,我有了object属性has_rain。我想以某种方式能够推理出,对于同一个人来说,不可能同时拥有has_rain(雨)和has_rain(无雨)我已经搜索了很多,但是没有找到我问题的答案。也许我在什么地方错过了。对不起,如果我没有解释好一切,这是我的第一个问

  • 我遇到了这个错误,它不允许我在表单中保存信息。初始数据在表单中显示良好,但保存起来很困难。希望有人能帮忙,我真的被困了 追踪: 内部 41 中的文件“C:\程序文件\Python35\lib\site-packages\django\core\处理程序\exception.py”。响应 = get_response(请求) 文件"C:\Program Files\Python35\lib\site

  • 问题内容: 因此,我使用猫鼬已经有一段时间了,我发现确实发生了一些很奇怪的事情。如果有人能启发我,那就太好了。 问题是,当使用猫鼬的.find()方法时,作为响应获得的对象充满了我不知道它来自何处的属性(我猜它们是内置属性,但无论如何),我只想通过I.select()属性进行迭代。得到它了?没有?好…解释得更好: 我声明了架构和模型: 然后,我想查找一个名称为John的文档,并检索除“名称”字段以