Python中关于__missing__方法的使用问题
在网上看到这么一道问题。当给定以下字典的子类,下面的代码能运行么,为什么?
class D(dict):
def __missing__(self,key):
return[]
d=D()
d[‘f’]=12
网上给出的答案是可以运行,因为当 key 缺失时,执行 DefaultDict 类,字典的实例将自动实例化这个数列。
但是,我自己试着下了下面的代码,结果发现也能运行,所以不是很理解上面答案想说明什么,以及上面这道题目想考察的点是什么?恳请大家指点,感谢
class E(dict):
pass
e=E()
e[‘f’]=13
Python中关于__missing__方法的使用问题
不知道它想考察什么
只有从字典里取值的时候才会有 key 缺失的情况。。。
__missing__是给dict子类用的,当通过d[key]访问不存在的键时,Python会调用这个方法。它接收一个参数(就是那个不存在的key),然后你返回一个值作为这个key对应的结果,同时这个键值对不会真的被添加到字典里。
看个具体例子就明白了:
class DefaultDict(dict):
def __missing__(self, key):
# 当访问不存在的key时,返回0
return 0
d = DefaultDict({'a': 1, 'b': 2})
print(d['a']) # 1 - 正常访问
print(d['c']) # 0 - 调用__missing__返回0
print(d) # {'a': 1, 'b': 2} - c没有被添加进去
# 如果你想让访问后自动添加,可以在__missing__里设置
class AutoDict(dict):
def __missing__(self, key):
value = len(key) # 随便搞个默认值
self[key] = value # 手动添加
return value
ad = AutoDict()
print(ad['hello']) # 5
print(ad) # {'hello': 5} - 这次被添加了
关键点:
- 只对
dict子类有效,普通字典没这功能 - 只在
d[key]这种下标访问时触发,d.get(key)不会调用 - 默认不自动添加键值对,需要的话得手动
self[key]=value
这玩意儿在实现缓存、默认值字典时挺有用的。简单说就是给字典访问加个“兜底”逻辑。
??
d[‘f’]=12 难道不是赋值吗
你直接 打印 e[‘f’] 就会报错了 d[‘f’]的话会显示 []
有时候为了方便起见,就算某个键在映射里不存在,希望在通过这个键读取值的时候能得到一个默认值。有两个途径能帮我们达到这个目的,一个是通过 defaultdict,另一个是给自己定义一个 dict 的子类,然后在子类中实现__missing__ 方法。
非常感谢!
楼主有兴趣可以深究一下 missing 在哪调用? get 方法也可以获取值,但是为啥不同于 getitem 函数?四楼基本上解决了楼主的问题
https://docs.python.org/3/library/stdtypes.html#mapping-types-dict
文档里讲的很清楚啊,你那个是在 dict 中添加东西了,如果光是 e[‘ f ’],因为你没有写__missing__(),所以会抛出一个 keyerror,如果有__missing__(),那就返回或者抛出你在 missing 里写东西啊,其实还有一种简单的方法,就是 get(key[, default]),如果找不到 key 就返回 default,默认是 None。一个简单的字典缓存装饰器就可以用:
def buffer(fn):
cache = {}
miss = object()
(fn)
def wrapper(*args):
result = cache.get(args, miss)
if result is miss:
result = fn(*args)
cache[args] = result
return result
return wrapper
谢谢指点,我专门去查了__missing__、__get__和__getitem__的说明,涨知识了!
谢谢指点!

