__setattr__和self .__ dict__之间的Python交互

时间:2012-06-05 17:36:11

标签: python

如果我像这样制作一个类实例

class MyClass(object):
    pass
x = MyClass()

然后我可以按如下方式在x上设置属性:

x.myAttr = 1x.__setattr__('myAttr', 1)

但是,如果我制作一个词典

d = {}

我无法在其上设置属性。例如,如果我这样做

d.__setattr__('myAttr', 1)

我收到错误“'dict'对象没有属性'myAttr'”如果我尝试也会发生同样的事情

d.myAttr = 1

我注意到在x.myAttr = 1的情况下实际发生的是

x.__dict__

使用新密钥进行更新,因此必须是

d.__setattr__

不起作用,因为d没有

d.__dict__

只是因为d 是一个词典。如果有人能够彻底解释这里发生了什么,我将非常感激。

所有python对象都有.__dict__吗?

为什么我尝试调用d.__setattr__会导致错误,说该属性不存在?

我应该知道内置类型的特定层次结构吗?一个简单的参考将非常感激。

python 2.6.4

Windows XP Pro x64 SP2

5 个答案:

答案 0 :(得分:4)

dict实例没有__dict__属性,因此您无法为其指定属性。 Python的大多数内置类(用C编写并以不同方式定义属性)都没有。如果您继承dict,则子类将具有__dict__属性,然后您可以将属性添加到子类的实例。

答案 1 :(得分:3)

从docs.python.org复制粘贴:

  

每个模块的特殊属性是__dict__。这是字典   包含模块的符号表。修改这个词典会   实际上改变了模块的符号表,但直接赋值给了   __dict__属性是不可能的(你可以写m .__ dict __ ['a'] = 1,   它将m.a定义为1,但你不能写m .__ dict__ = {})。   不建议直接修改__dict__。

http://docs.python.org/library/stdtypes.html

方法

这两行都是一样的:

x.__setattr__('a', b)
x.a = b

像__ add__一样:

x.__add__(b)
x + b

但是,您可以将dict .__ setattr__函数重新定义为您想要的任何内容

编辑第3条评论:

class x(object):
    def __init__(self):
        pass
    def __setattr__(self, a, b):
        print "nope, i will not set the attribute %s = %s" % (a,b)

c = x()
c.a = 4
print c.__dict__

将打印“nope,我不会设置属性a = 4 并且c.__dict__将没有属性“a”

答案 2 :(得分:1)

例外说明:

>>> class C(object):
...     __slots__ = ('a', 'b')
... 
>>> c = C()
>>> c.a = 1
>>> c.t = 2
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'C' object has no attribute 't'

插槽描述here

答案 3 :(得分:0)

self.__dict__dict。 假设,dict也有一个__dict__,它是一个递归定义,事情不会起作用: - )

答案 4 :(得分:0)

如果您执行x.myAttr = 1,那么您确实在x.__dict__['myAttr'] = 1。如果您执行x.__dict__.myAttr,则会收到与d.myAttr相同的错误。 。attribute赋值是为类而不是dicts定义的 - dict赋值是通过d['attribute']来代替的。