说,我有一个类Foo,扩展类Bar。我想稍微改写Foo的指导者。而且我甚至不想知道Bar的构造函数是什么。有没有办法做到这一点?
如果你不明白,我的意思是:
class Bar:
def __init__ (self, arg1=None, arg2=None, ... argN=None):
....
class Foo (Bar):
#Here i just want add additional parameter to constructor, but don't want to know anything about Bar's other parameters (arg1, arg2..., argN)
def __init__ (self, my_new_arg=None, ??? )
self.new_arg = my_new_arg
Bar.__init__(self, ??? )
有没有办法把短而优雅的东西放在???在这段代码? (也许是args / kwargs的一些变体)
答案 0 :(得分:44)
class Parent(object):
def __init__(self, a, b):
print 'a', a
print 'b', b
class Child(Parent):
def __init__(self, c, d, *args, **kwargs):
print 'c', c
print 'd', d
super(Child, self).__init__(*args, **kwargs)
test = Child(1,2,3,4)
<强>输出:强>
c 1 d 2 a 3 b 4
答案 1 :(得分:11)
@Acorn提出的*args, **kwds
解决方案是一个良好的开端(尽管我对问题的*args
部分提出异议)。这篇文章在Python的Super Considered Super。
*args
部分是不明智的,因为它不允许您在层次结构中插入新类,并且它阻止子类对可能具有不兼容位置参数的其他类使用多重继承。 **kwds
方法效果更好,因为它不强制执行调用链的特定排序。
另请注意,您可以使用命名参数将当前方法的命名参数从其余的关键字参数中分离并删除,然后再将它们传递到链中:
class Bar(object):
def __init__(self, arg1=None, arg2=None, argN=None):
print arg1, arg2, argN
class Foo(Bar):
def __init__(self, my_new_arg=None, **kwds):
super(Foo, self).__init__(**kwds)
self.new_arg = my_new_arg
print my_new_arg
f = Foo(my_new_arg='x', arg2='y')
让每个方法剥离它所需的参数很重要,因为像 object.__init__ 这样的父方法根本不需要参数。
最后要注意的是,如果您要使用 super ,请确保您的最顶级类是新式的(即它继承自 object 或其他一些内置类型。)