Mappings with Flexible Key Lookup(p70)
defaultdict
:类似与dict.default()
,可创建一个带有默认值类型的dict
,例如defaultdict(int)
,则遇到不存在的Key时,其取值为0。这个过程中会调用default_factory
,进而会调用special method__missing__
。__missing__
:该special method没有在dict
中定义,但如果在dict
的子类中定义__missing__
,则__getitem__
在遇到缺失的key时不会抛出KeyError
,而是会转而调用__missing__
。__missing__
在其他时候不会被调用,例如__contains__
。例3-7:
class StrKeyDict0(dict):
def __missing__(self, key):
if isinstance(key, str):
raise KeyError(key)
return self[str(key)]
def get(self, key, default=None):
try:
return self[key]
except KeyError:
return default
def __contains__(self, key):
return key in self.keys() or str(key) in self.keys()
有两处需要注意:
1.在__missing__
中,isinstance
的检查不可少。__missing__
被调用时,情况有三种:(1)是int
型,但其str
型在dict
中;(2)是int
型,且str
型不在dict
中;(3)是str
型但不在dict
中。如果没有isinstance
的过滤,str
型也不在dict
中时self[str(key)]
还会调用__missing__
,陷入死循环。
2.在__contains__
中,没有使用key in dict
而是用key in dict.keys()
是因为前者依然会调用__missing__
,而导致int
型的2
也会在dict
的keys
中。