深入 dict 机制,转化类变量
前言
一般情况下,我们在初始化 dict
(字典)时会直接 {key: value}
这么定义,亦或是使用 dict(key=value)
定义使用。而当处理对象变成了在一个类,在使用 obj.__dict__
魔法函数时,我们拿到的将会是这个类的实例变量,定义在类体中的类变量,我们是无法直接获取到的。
纷争开始
要想实现以 dict
的方式读取类/实例变量,我们duck不必使用库或其他依赖。下面我们看个例子:
上述代码在实际运行时,将会得到 TypeError: ‘A’ object is not iterable
的错误。这是因为 dict
对象是需要可迭代的,也就是需要属于 iter
,或者实现其所有方法。
我们再看一个例子:
当我们在 keys
这个方法上打上断点,以断点调试的方法运行程序时会发现,程序将会停在这一行代码上。这是因为,在默认情况下,我们在将对象直接传给 dict
的时候,dict
将会去这个类里寻找 keys
方法,以期望拿到字典的所有键。而这些键是由我们自己定义并返回的。再看下面的例子:
运行上述代码我们将会得到 TypeError: 'A' object is not subscriptable
的错误。这是因为,在默认情况下我们无法以中括号的方式去访问一个对象,但是我们可以使用一个方法,以改变这种情况。再看下面的例子:
运行代码之后将会发现,代码不再报错并且打印出来的数值与 __getitem___
所返回的值一样。这就是使用中括号调用的结果。如果我们想拿到某个变量所对应的值,我们可以使用 getattr
。如下所示:
上述代码将会打印出:
{'a': 1, 'b': 2, 'c': 3, 'd': 4} |
通过上述代码,我们已经将对象以字典的方法拿到了类里的变量,不论类变量还是实例变量。
片尾
以上便是本次文章的所有内容,介绍了如何以 dict
的方式访问实例变量。并没有同时介绍以对象的方式读取 dict
数据,因为反过来我们可以很容易的实现这个需求,这里推荐使用 namedtuple
内置库。
本文不涉及 dict
的基础知识以及底层原理,毕竟网上教程已经非常之充实了,这里不再赘述。
dict 的键,必须是可 hash 的。这是 dict
非常重要的一点。