【问题标题】:python: defaultdict with non-default argumentpython:带有非默认参数的defaultdict
【发布时间】:2014-09-21 02:46:16
【问题描述】:

我想要一个类似于 dictclass TestClass 的东西,它有一个非默认参数。当我访问时,我不知道所要求的元素是否已经出现。所以TestClass

class TestClass(object):
    def __init__(self, name):
        self.name = name
        self.state = 0
    def getName(self):
        self.state = self.state + 1
        return "%s -- %i" % (self.name, self.state)

然后是dict 和访问函数:

db = {}
def getOutput(key):
    # this is a marvel in the world of programming langauges
    if key not in db:
        db[key] = TestClass(key)
    return db[key]

以及实际测试代码:

if __name__ == "__main__":
    print "testing: %s" % getOutput('charlie').getName()

很好。但我想知道是否有更优雅的解决方案。浏览,defaultdict 进入我的脑海。但这不起作用,因为我无法将参数传递给default_factory

from collections import defaultdict
d = defaultdict(TestClass)
print "testing %s" % d['tom'].getOutput()

TypeError: __init__() takes exactly 2 arguments (1 given)...我还有其他解决方案吗?

此外,我想改进我的 Python。所以也欢迎任何其他建议;-)

【问题讨论】:

    标签: python dictionary karma-runner defaultdict


    【解决方案1】:

    defaultdict 工厂确实不接受争论。

    您可以创建自己的变体,但确实;诀窍在于定义__missing__ 方法:

    class TestClassDict(dict):
        def __missing__(self, key):
            res = self[key] = TestClass(key)
            return res
    

    只要访问不存在的keydict[key],就会调用__missing__ 方法。 defaultdict 每次都使用这个钩子返回factory(),但你可以提供自己的并传入key

    演示:

    >>> class TestClass(object):
    ...     def __init__(self, name):
    ...         self.name = name
    ...         self.state = 0
    ...     def getName(self):
    ...         self.state = self.state + 1
    ...         return "%s -- %i" % (self.name, self.state)
    ... 
    >>> class TestClassDict(dict):
    ...     def __missing__(self, key):
    ...         res = self[key] = TestClass(key)
    ...         return res
    ... 
    >>> db = TestClassDict()
    >>> db['charlie'].getName()
    'charlie -- 1'
    >>> db
    {'charlie': <__main__.TestClass object at 0x102f72250>}
    

    【讨论】:

    • 不错的解决方案。谢谢!
    • 这真的很酷,我能找到的唯一答案很容易显示如何做到这一点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 2019-12-14
    • 2020-01-03
    • 2021-06-20
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多