无法设置对象类的属性

无法设置对象类的属性

所以,当我回答时,我在玩Python这个问题,我发现这是无效的:

o = object()o.attr = 'hello'

由于AttributeError: 'object' object has no attribute 'attr'..但是,对于从对象继承的任何类,它都是有效的:

class Sub(object):
    passs = Sub()s.attr = 'hello'

印刷s.attr按预期显示“Hello”。为什么是这种情况?Python语言规范中指定不能将属性分配给普通对象的是什么?


凤凰求蛊
浏览 669回答 3
3回答

海绵宝宝撒

若要支持任意属性赋值,对象需要__dict__与对象关联的DECT,其中可以存储任意属性。否则,就无处可寻放新的属性。的实例object是吗?不随身携带__dict__-如果是的话,在可怕的循环依赖问题之前(自从dict,就像大多数其他的东西一样,继承了object-),这将是马鞍每一,每个对象在Python中使用dict,这意味着许多当前不具有或需要DECT的每个对象的字节(本质上,所有没有任意分配属性的对象都没有或需要一个dict)。例如,使用优秀的pympler项目(您可以通过SVN从这里),我们可以做一些测量.:>>> from pympler import asizeof>>> asizeof.asizeof({})144>>> asizeof.asizeof(23)16你不会想要int占144个字节,而不是只占16个字节,对吗?-)现在,当您创建一个类(从任何继承中继承)时,情况会发生变化.:>>> class dint(int): pass... >>> asizeof.asizeof(dint(23))184..__dict__ 是现在又增加了(加上更多的开销)-所以dint实例可以具有任意属性,但是您为这种灵活性付出了相当大的空间代价。如果你想intIt‘我们只是.一额外属性foobar.?这是一种罕见的需求,但Python确实为此提供了一种特殊的机制.>>> class fint(int):...   __slots__ = 'foobar',...   def __init__(self, x): self.foobar=x+100... >>> asizeof.asizeof(fint(23))80.不是相当小得像int小心你!(甚至是这两个人intS,其中之一self其中之一self.foobar-第二个可以重新分配),但肯定比dint.类具有__slots__特殊属性(字符串序列),则class语句(更准确地说,默认元类,type)不为该类的每个实例配备一个__dict__(因此,具有任意属性的能力),只是一个有限的、严格的“插槽”集(基本上每个位置都可以容纳一个对某个对象的引用)和给定的名称。为了换取失去的灵活性,您每个实例获得了大量字节(可能只有当您有成千上万个实例在运行时才有意义,但是,这里)。是用例)。

翻过高山走不出你

正如其他回答者所说,object没有__dict__. object的基类全类型,包括int或str..因此,无论由谁提供object也会成为他们的负担。即使是像一个简单的任选 __dict__每个值都需要一个额外的指针;这将为系统中的每个对象浪费额外的4-8字节内存,用于非常有限的实用程序。与在Python3.3+中执行虚拟类的实例不同,您可以(而且应该)使用types.SimpleNamespace为了这个。

叮当猫咪

因此,在研究我自己的问题时,我发现了关于Python语言的以下内容:您可以继承int这样的东西,您可以看到相同的行为:>>> class MyInt(int):&nbsp; &nbsp; &nbsp; &nbsp;pass>>> x = MyInt()>>> print x0>>> x.hello = 4>>> print x.hello4>>> x = x + 1>>> print x1>>> print x.helloTraceback (most recent call last):&nbsp; File "<interactive input>", line 1, in <module>AttributeError: 'int' object has no attribute 'hello'我假设最后的错误是因为add函数返回一个int,所以我必须重写以下函数__add__这样才能保留我的自定义属性。但是,当我想到像“int”这样的“对象”时,这一切对我来说都是有意义的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python