首页 文章

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

提问于
浏览
0

说我有这个示例代码,我正在为我正在举行的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 回答

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

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

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

    • 您的示例类是 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__ .

相关问题