【发布时间】:2013-04-24 16:26:51
【问题描述】:
这是对this question 的扩展,并提出了一个问题,您,我的 StackOverflowers 伙伴,希望能够帮助我。从引用的问题中,考虑最终的代码示例:
class A(object):
def __init__(self):
print "entering A"
print "leaving A"
class B(object):
def __init__(self):
print "entering B"
super(B, self).__init__()
print "leaving B"
class C(A,B):
def __init__(self):
print "entering c"
super(C, self).__init__()
print "leaving c"
正如海报所指出的,在初始化 C 时,B 的 __init__ 永远不会被调用。考虑到Raymond Hettinger's post,class A 的代码应该修改为也调用super().__init__():
class A(object):
def __init__(self):
print "entering A"
super(A, self).__init__()
print "leaving A"
到目前为止,我们都很好。但是,如果我们类的 __init__ 函数接受参数怎么办?让我们假设所有__init__ 函数都接受一个参数,为了保持一致性,我们简单地称它为foo,现在的代码是:
class A(object):
def __init__(self, foo):
print "entering A"
super(A, self).__init__(foo)
print "leaving A"
class B(object):
def __init__(self, foo):
print "entering B"
super(B, self).__init__(foo)
print "leaving B"
class C(A,B):
def __init__(self, foo):
print "entering c"
super(C, self).__init__(foo)
print "leaving c"
在这里我们遇到了障碍。在初始化任何类 A、B 或 C 时,我们最终会使用单个参数 foo 调用 object.__init__,而 TypeError: object.__init__() takes no parameters 会出错。但是,删除super().__init__ 函数之一将意味着在多重继承的情况下类不再协作。
毕竟,我的问题是如何解决这个问题?除了没有参数传递给 __init__ 函数的情况外,似乎在任何情况下都破坏了多重继承。
更新:
cmets 中的 Rob 建议剥离关键字参数(在 Raymond H 的帖子中引用)。在您更改代码之前,这实际上在多重继承的情况下非常有效。如果您的函数之一不再使用关键字参数之一,并且在不修改调用函数的情况下停止剥离它,您仍然会收到上面提到的 TypeError。因此,对于大型项目来说,这似乎是一个脆弱的解决方案。
【问题讨论】:
-
FWIW,“好的设计要求此方法在每种情况下都具有相同的调用签名” -- docs.python.org/2/library/functions.html#super
-
另外,请参阅rhettinger.wordpress.com/2011/05/26/super-considered-super,尤其是有关为
.__init__()使用关键字参数的部分。 -
@Robᵩ 理解,但我无法控制
object.__init__的签名,并且__init__类函数接受参数是非常正常的。似乎object.__init__应该被定义为__init__(*args, **kwargs)然后忽略传入的任何内容。 -
@Robᵩ 我已经引用了 Raymond Hettinger 的帖子。删除关键字可能会有所帮助...我将不得不考虑更多。
标签: python inheritance multiple-inheritance