为什么不能在python中为对象添加属性? [英] Why can't you add attributes to object in python?

查看:27
本文介绍了为什么不能在python中为对象添加属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(用 Python shell 编写)

<预><代码>>>>o = 对象()>>>o. 测试 = 1回溯(最近一次调用最后一次):文件<pyshell#45>",第 1 行,在 <module> 中o. 测试 = 1AttributeError: 'object' 对象没有属性 'test'>>>类测试1:经过>>>t = test1()>>>t.test回溯(最近一次调用最后一次):文件<pyshell#50>",第 1 行,在 <module> 中t.testAttributeError: test1 实例没有属性test">>>t.test = 1>>>t.test1>>>类 test2(对象):经过>>>t = test2()>>>t.test = 1>>>t.test1>>>

为什么对象不允许你向它添加属性?

解决方案

注意 object 实例没有 __dict__ 属性:

<预><代码>>>>目录(对象())['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__

在派生类中说明此行为的示例:

<预><代码>>>>类 Foo(对象):... __slots__ = {}...>>>f = Foo()>>>f.bar = 42回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中AttributeError: 'Foo' 对象没有属性 'bar'

引用 slots:

<块引用>

[...] __slots__ 声明采用一系列实例变量,并在每个实例中保留足够的空间来保存每个变量的值.节省了空间,因为 __dict__ 不是为每个实例创建的.

为了从评论中回答 ThomasH,OP 的测试类是一个旧式"类.试试:

<预><代码>>>>班级考试:及格...>>>getattr(test(), '__dict__'){}>>>getattr(object(), '__dict__')回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中AttributeError: 'object' 对象没有属性 '__dict__'

你会注意到有一个 __dict__ 实例.对象类可能没有定义__slots__,但结果是一样的:缺少__dict__,这是阻止动态分配属性的原因.我重新组织了我的答案以使其更清楚(将第二段移到顶部).

(Written in Python shell)

>>> o = object()
>>> o.test = 1

Traceback (most recent call last):
  File "<pyshell#45>", line 1, in <module>
    o.test = 1
AttributeError: 'object' object has no attribute 'test'
>>> class test1:
    pass

>>> t = test1()
>>> t.test

Traceback (most recent call last):
  File "<pyshell#50>", line 1, in <module>
    t.test
AttributeError: test1 instance has no attribute 'test'
>>> t.test = 1
>>> t.test
1
>>> class test2(object):
    pass

>>> t = test2()
>>> t.test = 1
>>> t.test
1
>>> 

Why doesn't object allow you to add attributes to it?

解决方案

Notice that an object instance has no __dict__ attribute:

>>> dir(object())
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__']

An example to illustrate this behavior in a derived class:

>>> class Foo(object):
...     __slots__ = {}
...
>>> f = Foo()
>>> f.bar = 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'bar'

Quoting from the docs on slots:

[...] The __slots__ declaration takes a sequence of instance variables and reserves just enough space in each instance to hold a value for each variable. Space is saved because __dict__ is not created for each instance.

EDIT: To answer ThomasH from the comments, OP's test class is an "old-style" class. Try:

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

and you'll notice there is a __dict__ instance. The object class may not have a __slots__ defined, but the result is the same: lack of a __dict__, which is what prevents dynamic assignment of an attribute. I've reorganized my answer to make this clearer (move the second paragraph to the top).

这篇关于为什么不能在python中为对象添加属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆