在类上覆盖dict()

时间:2017-10-08 02:21:25

标签: python python-3.x dictionary iterator override

我试图在Python中创建类似dict的类。

当你创建一个类时,你有一些方法告诉Python如何创建一个内置类。例如,如果用户在类的实例上使用__int__,则覆盖int()方法会告诉Python返回什么。 __float__也是如此。您甚至可以通过覆盖__iter__方法来控制Python如何创建类的可迭代对象(这可以帮助Python创建类的listtuple。我的问题是你如何告诉Python如何制作自定义类的dict?没有特殊的__dict__方法,那你怎么去做呢?我想要以下内容:

class Foo():
    def __dict__(self):
        return {
            'this': 'is',
            'a': 'dict'
        }

foo = Foo()
dict(foo) # would return {'this': 'is', 'a': 'dict'}

我已尝试让该类继承自dict,但由于子类尝试从dicttype继承而在代码中引发错误,因此继承来自dict不是可能的。还有其他办法吗?

此外,我已经覆盖了__iter__方法,因此它会返回dict_keyiterator个对象(当您在iter()上使用dict时返回的内容),但它似乎仍然无法发挥作用。

2 个答案:

答案 0 :(得分:2)

可以使用可迭代的对调用

dict,因此如果您将__iter__设计为返回可迭代的元组,则您的示例可以按照您的意愿运行:

class Foo:
    def __iter__(self):
        yield from {
            'this': 'is',
            'a': 'dict'
        }.items()

dict(Foo())
{'a': 'dict', 'this': 'is'}

如果您希望您的类的行为类似于python字典,那么迭代实例会迭代其键,您可以实现abc.Mapping定义的接口。

您可以通过实施__getitem____iter____len__,继承abc.Mapping,或实施所有__getitem__来实现这一目标,{ {1}},__iter__ __len____contains__keysitemsvaluesget和{{1 }}

答案 1 :(得分:1)

尽管来自@ForeverWintr的answer中的方法相当聪明且有效,但我认为它有点模糊,因为它利用了一些关于传递给{{1的参数的属性的神秘细节类构造函数。

出于这个原因,我可以在我的评论中说一个更好的方法,就是只添加一个能够做你想要的方法(另外还要说明如何简单地给它一个名字,说明究竟发生了什么)。

示例代码:

dict