问题 class,dict,self,init,args?


class attrdict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        self.__dict__ = self

a = attrdict(x=1, y=2)
print a.x, a.y

b = attrdict()
b.x, b.y  = 1, 2
print b.x, b.y

有人可以用文字解释前四行吗?我读了关于类和方法的内容。但这里看起来很混乱。


4308
2018-04-14 22:22


起源

这是泄漏内存的好方法。看到 bugs.python.org/issue1469629 作为解释,一个更好的选择。 - Jason Sundram


答案:


您没有在示例中使用位置参数。所以相关的代码是:

class attrdict(dict):
    def __init__(self, **kwargs):
        dict.__init__(self, **kwargs)
        self.__dict__ = self

在第一行中定义类 attrdict 作为的子类 dict。 在第二行中,您可以定义自动初始化实例的函数。你传递关键字参数(**kargs)这个功能。实例化时 a

 a = attrdict(x=1, y=2)

你实际上在打电话

attrdict.__init__(a, {'x':1, 'y':2})

dict实例核心初始化是通过初始化来完成的 dict 内置超类。这是在传递接收参数的第三行中完成的 attrdict.__init__。 从而,

dict.__init__(self,{'x':1, 'y':2})

品牌 self (实例 a) 一本字典:

self ==  {'x':1, 'y':2}

最好的事情发生在最后一行: 每个实例都有一个包含其属性的字典。这是 self.__dict__ (即 a.__dict__)。

例如,如果

a.__dict__ = {'x':1, 'y':2} 

我们可以写 a.x 要么 a.y 并分别获得值1或2。

所以,这就是第4行:

self.__dict__ = self

相当于:

a.__dict__ = a  where a = {'x':1, 'y':2}

然后我可以打电话 a.x 和 a.y

希望不是太乱。


5
2018-04-14 23:17



比接受的更好。 - Musaffa


我的逐行解释:

class attrdict(dict):

这一行声明了一个类attrdict作为内置dict类的子类。

def __init__(self, *args, **kwargs): 
    dict.__init__(self, *args, **kwargs)

这是你的标准 __init__ 方法。打电话给 dict.__init__(...) 是利用超级 class'(在本例中为dict)构造函数(__init__) 方法。

最后一行, self.__dict__ = self 使它传递给你的关键字参数(kwargs) __init__ 方法可以像属性一样被访问,即下面的代码中的a.x,a.y。

希望这有助于消除您的困惑。


7
2018-04-14 22:33



需要修复 __init__。在他们周围放置反叛,他们看起来像我的 __init__。 - Gary Kerr
这太有帮助了。谢谢! - kame


这是一篇很好的文章解释 __dict__

动态 字典

attrdict 类通过从字典继承然后设置对象来利用它 __dict__ 到那本字典。因此任何属性访问都发生在父词典上(即 dict 它继承的类)。

本文的其余部分对于理解Python对象也非常好:

Python属性和方法


4
2018-04-14 22:33