说我有这个示例代码,我正在为我正在举办的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().method
而不是明确命名superclass.method
我想尤其是后者更干,但是一旦我开始投入多重继承,super()就会变得更难解释。我想确保那里没有令人讨厌的陷阱,其他人会偶然发现。
答案 0 :(得分:4)
我不明白为什么你一般应该避免从内置类型派生。新的类的到来实现了这一点被认为是一种改进,甚至在此之前,标准库提供了UserDict
和UserList
类来派生。当然,你必须在每个特定的情况下评估继承或组合是否是你需要的,但这就是OOP中的总是如此 - 这里没有关于内置类型的特殊内容。
我不建议在示例中使用super()
。仅在所有合作方法具有相同签名或至少合作签名时才有用。对于单继承和“无钻石”多重继承,在我看来显式调用基类方法是好的。如果你想用钻石进行多重继承,你就不得不使用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__
。