![](/img/trans.png)
[英]Is there a clever way to pass the key to defaultdict's default_factory?
[英]Accessing key in factory of defaultdict
我正在尝试做类似的事情:
from collections import defaultdict
import hashlib
def factory():
key = 'aaa'
return { 'key-md5' : hashlib.md5('%s' % (key)).hexdigest() }
a = defaultdict(factory)
print a['aaa']
(实际上,我需要访问工厂中的密钥的原因不是为了计算md5
,而是出于其他原因;这只是一个示例)
如您所见,在工厂中,我无法访问密钥:我只是强迫它,这没有任何意义。
是否可以以我可以访问工厂密钥的方式使用defaultdict
?
defaultdict
__missing__
没有将key
传递给工厂函数。
如果
default_factory
不是None
, 则不带参数调用它以提供给定键的默认值,此值将插入键的字典中并返回。
使用自定义__missing__
方法创建自己的字典类。
>>> class MyDict(dict):
... def __init__(self, factory):
... self.factory = factory
... def __missing__(self, key):
... self[key] = self.factory(key)
... return self[key]
...
>>> d = MyDict(lambda x: -x)
>>> d[1]
-1
>>> d
{1: -1}
不幸的是,不是直接的,因为defaultdict指定必须在没有参数的情况下调用default_factory:
http://docs.python.org/2/library/collections.html#collections.defaultdict
但是可以使用defaultdict作为具有所需行为的基类:
class CustomDefaultdict(defaultdict):
def __missing__(self, key):
if self.default_factory:
dict.__setitem__(self, key, self.default_factory(key))
return self[key]
else:
defaultdict.__missing__(self, key)
这对我有用:
>>> a = CustomDefaultdict(factory)
>>> a
defaultdict(<function factory at 0x7f0a70da11b8>, {})
>>> print a['aaa']
{'key-md5': '47bce5c74f589f4867dbd57e9ca9f808'}
>>> print a['bbb']
{'key-md5': '08f8e0260c64418510cefb2b06eee5cd'}
在几种情况下,我想要一个带有工厂密钥的 defaultdict,我发现lru_cache
也解决了我的问题:
import functools
@functools.lru_cache(maxsize=None)
def use_func_as_dict(key='') # Or whatever type
with open(key, 'r') as ifile:
return ifile.readlines()
f1 = use_func_as_dict('test.txt')
f2 = use_func_as_dict('test2.txt')
# This will reuse the old value instead of re-reading the file
f3 = use_func_as_dict('test.txt')
assert f3 is f1
这实际上在理论上更有意义,因为您追求的是输入的函数而不是一致的虚拟回退。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.