是否有任何“好”的方法来管理继承层次结构中的args和kwargs,就像我在这段代码中尝试过的那样。我的意思是没有在kwargs或类似的东西中获得具有指定键的值...
应该显示1 2 3 4
:
class Parent(object):
def __init__(self, motherArg1, motherArg2=100):
self.motherArg1 = motherArg1
self.motherArg2 = motherArg2
def printParent(self):
print self.motherArg1
print self.motherArg2
class Child(Parent):
def __init__(self, childArg1, *args, childArg2=100, **kwargs): # Doesn't work here
super(Child, self).__init__(*args, **kwargs)
self.childArg1 = childArg1
self.childArg2 = childArg2
def printChild(self):
print self.childArg1
print self.childArg2
child = Child(1, 3, childArg2=2, motherArg2=4)
child.printChild()
child.printParent()
语法不好:期望“);”在* args之后。
并且def __init__(self, childArg1, childArg2=100, *args, **kwargs)
是正确的语法,但不起作用。
child = Child(1, childArg2=2, 3, motherArg2=4)
时,我得到 SyntaxError:关键字arg之后的非关键字arg child = Child(1, 3, childArg2=2, motherArg2=4)
时,我得到 TypeError:__ init __()获得了关键字参数'childArg2'的多个值 答案 0 :(得分:2)
在Python 2中,您必须将*args
参数放在任何显式关键字参数之后:
def __init__(self, childArg1, childArg2=100, *args, **kwargs):
但是,您无法使用其他位置参数无论如何,因为它们被childArg2
参数捕获:
>>> child = Child(1, 3, childArg2=2, motherArg2=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() got multiple values for keyword argument 'childArg2'
您唯一的选择是从**kwargs
字典中获取关键字参数:
def __init__(self, childArg1, *args, **kwargs):
childArg2 = kwargs.pop('childArg2', 2)
这使childArg2
仅作为显式关键字参数工作,*args
捕获所有其他位置参数:
>>> class Parent(object):
... def __init__(self, motherArg1, motherArg2=100):
... self.motherArg1 = motherArg1
... self.motherArg2 = motherArg2
... def printParent(self):
... print self.motherArg1
... print self.motherArg2
...
>>> class Child(Parent):
... def __init__(self, childArg1, *args, **kwargs):
... childArg2 = kwargs.pop('childArg2', 2)
... super(Child, self).__init__(*args, **kwargs)
... self.childArg1 = childArg1
... self.childArg2 = childArg2
... def printChild(self):
... print self.childArg1
... print self.childArg2
...
>>> child = Child(1, 3, childArg2=2, motherArg2=4)
>>> child.printChild()
1
2
>>> child.printParent()
3
4
答案 1 :(得分:1)
当您将父级printChild
重命名为printParent
(并修复print
s)时,它已在python 3中正常工作,如建议的那样:
1
2
3
4
但你也可以让它适用于python2。你可以通过删除kwargs
中与儿童相关的条目,然后再将它们传递给父母。
代码(适用于python3):
class Parent(object):
def __init__(self, motherArg1, motherArg2=100):
self.motherArg1 = motherArg1
self.motherArg2 = motherArg2
def printParent(self):
print(self.motherArg1)
print(self.motherArg2)
class Child(Parent):
def __init__(self, childArg1, *args, childArg2=100, **kwargs):
super(Child, self).__init__(*args, **kwargs)
self.childArg1 = childArg1
self.childArg2 = childArg2
def printChild(self):
print(self.childArg1)
print(self.childArg2)
child = Child(1, 3, childArg2=2, motherArg2=4)
child.printChild()
child.printParent()
python2的代码
class Parent(object):
def __init__(self, motherArg1, motherArg2=100):
self.motherArg1 = motherArg1
self.motherArg2 = motherArg2
def printParent(self):
print(self.motherArg1)
print(self.motherArg2)
class Child(Parent):
def __init__(self, childArg1, *args, **kwargs):
# this shows the concept, it can be formulated more elegantly
# with @Martijn Pieters answer's 'pop':
if 'childArg2' in kwargs:
childArg2 = kwargs['childArg2']
del kwargs['childArg2']
else:
childArg2 = 2
super(Child, self).__init__(*args, **kwargs)
self.childArg1 = childArg1
self.childArg2 = childArg2
def printChild(self):
print(self.childArg1)
print(self.childArg2)
child = Child(1, 3, childArg2=2, motherArg2=4)
child.printChild()
child.printParent()