【问题标题】:Construct a object which can be mapped or un packed构造一个可以映射或解包的对象
【发布时间】:2014-04-27 13:38:23
【问题描述】:

所以我有这个(当然真事更复杂):

class test(object):
    i = -1

    def keys(self):
        return ["a", "b"]

    def __getitem__(self, item):
        return {"a": 0, "b": 1}[item]

    def __len__(self):
        return 2

    def __contains__(self, item):
        if item in ["a", "b"]:
            return True
        return False

    def __iter__(self):
        return self

    def next(self):
        self.i += 1
        if self.i > 1:
            raise StopIteration()

        return ["a", "b"][self.i]

我想要做的是这个(再次真实的事情更复杂):

> t = test()
> dict(t)
 {'a': 0, 'b': 1}
> dict(**t) 
 {'a': 0, 'b': 1}

这工作得很好,但是如果我将类定义为字典的子类,这就是我想要的,我希望我的对象表现得像一个字典,在膝盖下有一些隐藏的技巧(再次确保它在实际代码中更有意义):

class test(dict):
     .... same code here ....

在这种情况下,dict(t)dict(**t) 将返回一个空字典 {},但 [k for k in t] 将返回 ['a','b']

我想念什么?看来我确实需要重新声明一些 dict 函数,但我认为 __getitem__, __iter__, __len__, __contains__ and keys 方法足以做到这一点。我试图重新声明 iterkeys、itervalues、copy、get 等,但似乎没有任何效果。

谢谢。

【问题讨论】:

  • 我觉得你需要重新定义构造函数来调用super。
  • 如果你不首先覆盖__init__,则不会
  • collections.UserDict 简化了行为类似于字典的自定义类的创建。
  • 搜索python映射协议。您可能会考虑继承 collections.abc.MutableMapping 而不是继承 dict
  • 到目前为止你展示的所有方法都由dict处理。通过继承dict,你需要做的就是用你的{"a": 0, "b": 1}作为参数调用一个super

标签: python dictionary


【解决方案1】:
 class test(dict):
    i = -1

    def __init__(self):
        super(test, self).__init__({"a": 0, "b": 1})

    def keys(self):
        return ["a", "b"]

    def __getitem__(self, item):
        return {"a": 0, "b": 1}[item]

    def __len__(self):
        return 2

    def __contains__(self, item):
        if item in ["a", "b"]:
            return True
        return False

    def __iter__(self):
        return self

    def next(self):
        self.i += 1
        if self.i > 1:
            raise StopIteration()

        return ["a", "b"][self.i]

t = test()
print dict(t)
# output: {'a': 0, 'b': 1}
print dict(**t)
# output: {'a': 0, 'b': 1}

当然,在类定义中硬编码{'a': 0, 'b': 1} 不是一个好主意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    相关资源
    最近更新 更多