【问题标题】:How to subclass an OrderedDict?如何继承 OrderedDict?
【发布时间】:2012-06-25 20:16:28
【问题描述】:

子类化 Python dict 按预期工作:

>>> class DictSub(dict):
...     def __init__(self):
...         self[1] = 10
...         
>>> DictSub()
{1: 10}

但是,用 collections.OrderedDict 做同样的事情是行不通的:

>>> import collections
>>> class OrdDictSub(collections.OrderedDict):
...     def __init__(self):
...         self[1] = 10
...         
>>> OrdDictSub()
(…)
AttributeError: 'OrdDictSub' object has no attribute '_OrderedDict__root'

因此,OrderedDict 实现使用私有的__root 属性,从而防止子类OrdDictSub 表现得像DictSub 子类。为什么?如何从 OrderedDict 继承?

【问题讨论】:

    标签: python inheritance subclass ordereddictionary


    【解决方案1】:

    您需要从您的__init__ 调用OrderedDict.__init__

    class OrdDictSub(collections.OrderedDict):
        def __init__(self):
            super(OrdDictSub, self).__init__()
    

    你还没有给OrderedDict 一个初始化自己的机会。从技术上讲,您也希望为您的dict 子类执行此操作,因为您需要一个完全初始化的dictdict 没有它也能正常工作,这只是运气。

    【讨论】:

    • 谢谢。我的错,确实。确实,我受到了dict的影响。前段时间我什至问过一个关于 dict 的问题(stackoverflow.com/questions/2033150/…)!
    • 你不想在 init 中使用 args 和 kwargs 吗? def __init__(self, *args, **kwargs): super(OrdDictSub, self).__init__(*args, **kwargs)
    【解决方案2】:

    尝试在__init__ 方法中初始化超类:

    def __init__(self):
        collections.OrderedDict.__init__(self)
        self[1] = 10
    

    这是初始化子类的正常方式。您通常必须调用超类的__init__ 方法,但如果您不了解超类的实现,您确实应该调用__init__

    【讨论】:

    • 使用super()调用超类的方法
    • @DietrichEpp:很好的答案,但使用super() 不是风格问题:如果您自己的类是子类,使用它(而不是使用显式超类)很重要。参考示例:rhettinger.wordpress.com/2011/05/26/super-considered-super。此外,使用super() 使代码更易于维护(更改类的名称更容易)。
    • @EOL:我可以接受 super() 是要走的路,但我不同意你的“进一步”:我会说它是一个半打中的六个,在 Python 2 中。如果您想更改 OrdDictSub 类的名称但仍保留相同的父级,那么使用 super() 意味着您必须在两个地方而不是一个地方进行。另一方面,如果您想保留 OrdDictSub 名称但更改父名称,那么 not 使用 super() 意味着您必须在两个地方而不是一个地方这样做。幸运的是,这已在 Python 3 中得到修复(只需调用 super() 不带参数)。
    • @JohnY:同意,super() 在 Python 2 中类名更改的情况下不是更方便,但仅限于 Python 3。
    • @JohnY:Martijn Pieters 的这个出色的回答涵盖了它:stackoverflow.com/a/18208725/82294——如果你认为 Martijn 错了,去那边争论吧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    相关资源
    最近更新 更多