关于python:class,dict,self,init,args?

class, dict, self, init, args?

1
2
3
4
5
6
7
8
9
10
11
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

有人能用文字解释前四行吗?我读过关于类和方法的书。但这里看起来很混乱。


我一行一行的拍摄说明:

1
class attrdict(dict):

此行将类attrdict声明为内置dict类的子类。

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

这是你的标准方法。对dict.__init__(...)的调用是使用super类'(在本例中是dict)构造函数(__init__方法)。

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

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


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

1
2
3
4
class attrdict(dict):
    def __init__(self, **kwargs):
        dict.__init__(self, **kwargs)
        self.__dict__ = self

在第一行中,您将类attrdict定义为dict的子类。在第二行中,您定义了自动初始化实例的函数。将关键字参数(**kargs传递给此函数。当您实例化a时:

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

你在打电话

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

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

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

使self(实例a)成为字典:

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

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

例如,如果

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

我们可以写a.xa.y并分别得到值1或2。

所以,这就是第4行所做的:

1
self.__dict__ = self

相当于:

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

然后我可以打电话给a.xa.y

希望不是太乱。


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

动态口述

attrdict类通过继承字典,然后将对象的__dict__设置为字典来利用它。因此,对父字典(即它继承的dict类)进行任何属性访问。

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

python属性和方法