如果我像这样制作一个类实例
class MyClass(object):
pass
x = MyClass()
然后我可以按如下方式在x上设置属性:
x.myAttr = 1
或x.__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
答案 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']
来代替的。