为什么不能在python中向对象添加属性?

发布于 2021-01-29 19:36:43

(用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
>>>

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

关注者
0
被浏览
62
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    请注意,object实例没有__dict__属性:

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

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

    >>> 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'
    

    引用以下文档slots

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

    编辑:要从评论中回答ThomasH,OP的测试类是“旧式”类。尝试:

    >>> 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__'
    

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



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看