类、字典、自身、初始化、参数?

12 投票
3 回答
10329 浏览
提问于 2025-04-15 21:37
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

有人能用简单的话解释一下前四行吗?我读过关于类和方法的内容,但这里看起来很让人困惑。

3 个回答

4

这里有一篇不错的文章,讲解了 __dict__ 的内容:

动态 字典

attrdict 类通过继承字典来实现这个功能,然后把对象的 __dict__ 设置为那个字典。所以,当你访问属性时,实际上是在访问它继承的父类字典(也就是 dict 类)。

文章的其他部分也很不错,能帮助你理解 Python 对象:

Python 属性和方法

7

我来逐行解释一下:

class attrdict(dict):

这一行定义了一个叫做 attrdict 的类,它是内置字典类 dict 的子类。

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

这是一个标准的 __init__ 方法。调用 dict.__init__(...) 是为了使用父类(在这里是 dict)的构造方法 (__init__)。

最后一行 self.__dict__ = self 的作用是让你传给 __init__ 方法的关键字参数(kwargs)可以像属性一样访问,也就是说,你可以用 a.x、a.y 这样的方式来访问下面代码中的内容。

希望这能帮助你理清思路。

5

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

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 这个内置的父类来完成的。这在第三行中完成,传递了在 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.xa.y,分别得到值 1 或 2。

所以,这就是第四行的作用:

self.__dict__ = self

相当于:

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

然后我可以调用 a.xa.y

希望这样解释不会太乱。

撰写回答