superclass.method(对象,parms)有什么问题?

时间:2012-03-29 13:21:22

标签: python-3.x multiple-inheritance super

说我有这个示例代码,我正在为我正在举办的Python课程编写代码:

class Enum(dict):
  def __init__(self, *values):
    values = {mnemo: num
      for num, mnemo in enumerate(values)}
    dict.__init__(self, values) # ← this
  def __getattr__(self, name):
    return self[name]

这似乎按预期工作,至少在一个浅薄的方法上,但我在互联网上的文献大部分时间看到的是:

我想尤其是后者更干,但是一旦我开始投入多重继承,super()就会变得更难解释。我想确保那里没有令人讨厌的陷阱,其他人会偶然发现。

1 个答案:

答案 0 :(得分:4)

  1. 我不明白为什么你一般应该避免从内置类型派生。新的类的到来实现了这一点被认为是一种改进,甚至在此之前,标准库提供了UserDictUserList类来派生。当然,你必须在每个特定的情况下评估继承或组合是否是你需要的,但这就是OOP中的总是如此 - 这里没有关于内置类型的特殊内容。

  2. 我不建议在示例中使用super()。仅在所有合作方法具有相同签名或至少合作签名时才有用。对于单继承和“无钻石”多重继承,在我看来显式调用基类方法是好的。如果你想用钻石进行多重继承,你就不得不使用super(),但你必须仔细设计你的方法,参见Raymond Hettinger's "Python's super() considered super!"

    在所有涉及的方法具有完全相同的签名的情况下使用super()通常是安全的,包括__getattr__()__setattr__()等方法。

  3. 您的示例类是Enum类型的一个相当可疑的实现,但不是您在帖子中提到的任何原因。它混合了两个名称空间:dict属性的名称空间和枚举条目。试试Enum("clear", "update")看看我的意思。在这种特殊情况下,后续实施会更好:

    class Enum(object):
        def __init__(self, *values):
            vars(self).update({mnemo: num for num, mnemo in enumerate(values)})
    

    这会将枚举条目作为属性添加到标准实例,而不会派生自dict。每个自定义类实例都会带来自己的字典,即__dict__