Python 在defaultdict的工厂中访问密钥

Python 在defaultdict的工厂中访问密钥,python,python-2.7,dictionary,defaultdict,Python,Python 2.7,Dictionary,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,而是出于其他原因;这只是一个示例)

我正在尝试做类似的事情:

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
不会将
钥匙
传递给出厂功能

如果
default\u factory
不是
None
,则调用而不带参数 为给定键提供默认值,该值将插入 字典找钥匙,然后返回

使用自定义的
\uuuu missing\uuu
方法创建自己的字典类

>>> 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指定调用默认工厂时必须没有参数:

但可以将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'}
>a=CustomDefaultdict(工厂)
>>>a
defaultdict(,{})
>>>打印一个['aaa']
{'key-md5':'47bce5c74f589f4867dbd57e9ca9f808'}
>>>打印一个['bbb']
{'key-md5':'08F8E0260C64418510CEFB206EEE5CD'}

出于好奇,为什么需要
defaultdict
,它只是用来纠正缺失的值吗?因为除了返回
{}
,这就是它所做的一切?是的,它是为字典中缺少的键提供值。这就是默认dict的全部要点,不是吗?问题是,我存储在defaultdict中的(真实的)数据结构根据键的不同有不同的字段。因此,每当我试图访问一个不存在的元素时,我都需要在工厂中创建它,并使用
defaultdict
的键作为参数。我害怕你做一些超出常规的事情。请参阅@falsetru的解决方案,因为这正是我要向您建议的,以防自定义生成字典:)可能重复的。我仍然不理解defaultdict为什么不支持这种类型的工厂。有人能解释一下吗?@midas我不确定,但我的猜测是,在保持只插入任何类型的构造函数而不需要参数的能力的同时,没有什么好方法可以做到这一点(
defaultdict(int)
defaultdict(MyClass)
)。@ralokt,有人能解释一下为什么要使用工厂而不是对象,比如
defaultdict(0)
?@Alexey,因为我猜有时候静态值并不能减少它。这将比不传递丢失的密钥更糟糕,因为它将无法传递给任何人。而且,具有可变类型的静态值是完全不可能的,每个缺少的键都指向同一个对象。我同意不能访问
键是愚蠢的。对于不需要该键的情况,您可以忽略它,例如,
defaultdict(lambda键:0)
无需使用
defaultdict
作为基类:
dict
可以直接子类化。