Python 找不到dict.iteritems(类)的重写

Python 找不到dict.iteritems(类)的重写,python,Python,我有一个类,它已经替换了\uuuu iter\uuuu,以隐藏额外的不需要的数据。我通过将iteritems设置为dict.iteritems或dict.items使我的其余代码向后兼容,具体取决于python版本,然后我可以调用iteritems(class\u对象),但我的类似乎无法正常工作 用一个例子更容易解释: class Test(dict): def __init__(self, some_dict): self.some_dict = some_dict

我有一个类,它已经替换了
\uuuu iter\uuuu
,以隐藏额外的不需要的数据。我通过将
iteritems
设置为
dict.iteritems
dict.items
使我的其余代码向后兼容,具体取决于python版本,然后我可以调用
iteritems(class\u对象)
,但我的类似乎无法正常工作

用一个例子更容易解释:

class Test(dict):
    def __init__(self, some_dict):
        self.some_dict = some_dict
        super(self.__class__, self).__init__(self.some_dict)
    def __iter__(self):
        for k, v in self.some_dict.iteritems():
            yield k, v['value']

test_dict = {
    'a': {'value': 'what',
          'hidden': 123},
    'b': {'value': 'test'}
}
如果我执行
Test(Test\u dict)。\uu iter\uuu()
,那么它将正确地返回
{'a':'what','b':'Test'}

如果我向类中添加
iteritems=\uuuu iter\uuuu
,那么它在执行
Test(Test\u dict.iteritems()

但是,无论我尝试什么,执行
dict.iteritems(Test(Test_dict))
默认为标准dict迭代,并返回
{'a':{'hidden':123,'value':'what'},'b':{'value':'Test'}

我尝试了几个跟踪函数,但它们不够深入,无法弄清楚发生了什么。

dict.iteritems()方法直接进入
dict
实现的内部数据结构。您传入了dict的一个子类
dict
,这样它就可以访问这些相同的数据结构。你不能无视这种行为

并不是说dict.iteritems()会使用;后者只生成键,而不是键值对

您应该以不同的方式定义
iteritems
;给定Python 2的
PY3
布尔变量
False
True
否则:

from operator import methodcaller

iteritems = methodcaller('items' if PY3 else 'iteritems')
现在,根据需要将
iteritems(object)
转换为
object.iteritems()
object.items()
,并始终调用正确的方法

接下来,为了扩展字典行为,我将子类(*),而不是子类化
dict

这实现了
dict
提供的所有相同方法,除了
copy
dict.fromkeys()
类方法

您可以改为从继承,这将添加剩下的两个方法:

try:
    # Python 2
    from UserDict import UserDict
except ImportError:
    from collections import UserDict


class Test(UserDict):
    def __iter__(self):
        for k, v in self.data.iteritems():
            yield k, v['value']
在这种情况下,只需要一个备用的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

在这两种情况下,您仍然不能在这些对象上使用
dict.iteritems
,因为该方法只能用于实际的
dict
对象



(*)
collections.MutableMapping
是该类的Python 2位置,Python3的官方位置是collections.abc.MutableMapping,但是有一些别名支持Python2兼容的代码。

我不知道为什么您继承了
dict
,但保留了对
self.some\u dict
中字典的额外引用。您可以只使用
self.iteritems()
。请注意,通常情况下,字典上的迭代只生成键,而不是键值对。为什么需要
dict.iteritems
才能工作?这不是一个常规的Python方法,它涉及到
dict
内部。既然你把
dict
子类化了,那是可能的,也是允许的。@MartijnPieters我用
\uuuu init\uuuu
做错事了吗?我希望继承所有正常的dict函数,但仍然能够轻松访问和更改所有数据。至于不执行self.iteritems()
,主要是为了使它与代码的其余部分保持一致。我一直在使用
iteritems(dict)
来保持它与python 2和python 3的兼容性,如果可能的话,我更愿意保持这种风格。
dict.iteritems
是超类的方法。它忽略子类中的任何重写。@fafl:更重要的是,它的实现不在实例上使用任何其他方法。它直接进入构成实例状态的结构并访问
ma_表
和其他C级数据结构。哦,该死的,
methodcaller
工作得很好,我基本上一直在做
iteritems=dict.items if PY3 else dict.items
。我的类已经增长了,但在继承的基础上,它有点像
UserDict
,而
MutableMapping
可能会被使用得更高一点,所以适应起来可能不会太糟糕。谢谢:)@Peter:你也可以用;它是麻省理工学院专门许可的,因此您可以根据需要将其自由复制到您的项目中,或者您可以使其成为
setup.py
依赖项。@Peter:
six
在Python 3上实现
iteritems()
as
iter(d.items())
,因为这在技术上更正确。哦,等一下,我可能用错了代码,
methodcaller
是否仍然完全绕过该类?
six.py
中的
iteritems
比我想象的要简单得多,这个文件在前面可能非常有用,但是其他一些代码完全依赖于我自己的兼容文件:P
methodcaller(name\u of\u method)(object)
将在
对象上执行方法的
名称。它是什么类型的对象并不重要。如果希望调用类,则需要在类上提供
iteritems()
的实现。如果子类化了
dict
,但没有提供自己的
iteritems()
实现,仍然会得到错误的结果。
try:
    # Python 2
    from UserDict import UserDict
except ImportError:
    from collections import UserDict


class Test(UserDict):
    def __iter__(self):
        for k, v in self.data.iteritems():
            yield k, v['value']