我们是可以继承dict 的,代码如下
class My_dict(dict):
def __setitem__(self, key, value):
super().__setitem__(key,value*value)
a=My_dict(one=2)
print(a["one"])
打印结果:
2
My_dict 子类继承了dict ,并调用了父类的setitem,并针对value做了一个乘积,
从结果我们发现并没有乘积。为了找原因也得爬源码查找dict 的setitem方法如下
def __setitem__(self, *args, **kwargs): # real signature unknown
""" Set self[key] to value. """
pass
这个方法没有做任何处理,并不适用继承dict,难道就没有办法吗,
python 给你关闭一扇窗,会给你再开一个门,这个门就是
继承Userdict 可以实现乘积,请看代码
from collections import UserDict
class My_dict(UserDict):
def __setitem__(self, key, value):
super().__setitem__(key,value*value)
a=My_dict(one=2)
print(a["one"])
打印结果:
4
刨析源码查看 这个方法
def __setitem__(self, key, item): self.data[key] = item
道理很明白了吧 ,我也不用解释了。
下边介绍重量级的人物就是 defautdict
因为他可以重写一个魔法函数 missing ,我们按照顺序介绍下
查看 UserDict的getitem 方法如下:
def __getitem__(self, key):
if key in self.data:
return self.data[key]
if hasattr(self.__class__, "__missing__"):
return self.__class__.__missing__(self, key)
raise KeyError(key)
有两个if 语句
1.如果key存在返回value
2.如果不存在就return missing魔法函数 。
我们查看 defautdict 里面的missing 魔法函数
def __missing__(self, key): # real signature unknown; restored from __doc__
"""
__missing__(key) # Called by __getitem__ for missing key; pseudo-code:
if self.default_factory is None: raise KeyError((key,))
self[key] = value = self.default_factory()
return value
"""
pass
从上边的描述有个关键信息 self[key] = value = self.default_factory()
如果不存在我会给个默认值
default_factory() 这个方法有property属性,可以自己查下,我在以后的章节再介绍。
代码例子如下:
from collections import UserDict,defaultdict
my_dict={"person":1}
my_dict=defaultdict(int)
value=my_dict["animal"]
print(value)
打印结果:
0
如果没有 defaultdict 一定会报keyerror,自己可以试试。
由于defaultdict 有missing 方法,避免了报keyerror。
下边讲讲基本的用处
1.类型名称作为初始化函数参数
from collections import UserDict,defaultdict
fruit=["apple","banana","orange"]
v=defaultdict(int)
for i in fruit:
v[i]+=1
print(v)
打印结果:
defaultdict(<class 'int'>, {'apple': 1, 'banana': 1, 'orange': 1})
如果defaultdict(int) 初始化数值默认是0,如果是str是空, 如果是list是[],如果是dict是{}
自己可以尝试下
2.可以调用函数作为初始化函数参数
from collections import UserDict,defaultdict
def add():
return 8+9
v=defaultdict(add)
value=v["boody"]
print(value)
打印的结果是:
17
defautdict 作为dict 子类用处很大,上边的例子调用了方法作为默认值,这个在实际应用的用的最多,请大家记牢。