为了账号安全,请及时绑定邮箱和手机立即绑定

无法设置对象类的属性

无法设置对象类的属性

凤凰求蛊 2019-07-04 17:27:04
无法设置对象类的属性所以,当我回答时,我在玩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语言规范中指定不能将属性分配给普通对象的是什么?
查看完整描述

3 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

若要支持任意属性赋值,对象需要__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__(因此,具有任意属性的能力),只是一个有限的、严格的“插槽”集(基本上每个位置都可以容纳一个对某个对象的引用)和给定的名称。

为了换取失去的灵活性,您每个实例获得了大量字节(可能只有当您有成千上万个实例在运行时才有意义,但是,这里)。用例)。


查看完整回答
反对 回复 2019-07-04
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

正如其他回答者所说,object没有__dict__object的基类类型,包括intstr..因此,无论由谁提供object也会成为他们的负担。即使是像一个简单的任选 __dict__每个值都需要一个额外的指针;这将为系统中的每个对象浪费额外的4-8字节内存,用于非常有限的实用程序。


与在Python3.3+中执行虚拟类的实例不同,您可以(而且应该)使用types.SimpleNamespace为了这个。


查看完整回答
反对 回复 2019-07-04
?
叮当猫咪

TA贡献1776条经验 获得超12个赞

因此,在研究我自己的问题时,我发现了关于Python语言的以下内容:您可以继承int这样的东西,您可以看到相同的行为:


>>> class MyInt(int):

       pass


>>> x = MyInt()

>>> print x

0

>>> x.hello = 4

>>> print x.hello

4

>>> x = x + 1

>>> print x

1

>>> print x.hello

Traceback (most recent call last):

  File "<interactive input>", line 1, in <module>

AttributeError: 'int' object has no attribute 'hello'

我假设最后的错误是因为add函数返回一个int,所以我必须重写以下函数__add__这样才能保留我的自定义属性。但是,当我想到像“int”这样的“对象”时,这一切对我来说都是有意义的。


查看完整回答
反对 回复 2019-07-04
  • 3 回答
  • 0 关注
  • 668 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信