为什么不能在子类的__init__中传递* args和** kwargs
为了理解 args和* kwargs,当我遇到这个问题时,我进行了一些搜索* args和**
kwargs?
所选答案下方的答案引起了我的注意,这是:
class Foo(object):
def __init__(self, value1, value2):
# do something with the values
print value1, value2
class MyFoo(Foo):
def __init__(self, *args, **kwargs):
# do something else, don't care about the args
print 'myfoo'
super(MyFoo, self).__init__(*args, **kwargs)
我在此示例上尝试了一些操作,并以这种方式运行代码:
class Foo(object):
def __init__(self, value1, value2):
# do something with the values
print 'I think something is being called here'
print value1, value2
class MyFoo(Foo):
def __init__(self, *args, **kwargs):
# do something else, don't care about the args
print args, kwargs
super(MyFoo, self).__init__(*args, **kwargs)
foo = MyFoo('Python', 2.7, stack='overflow')
我懂了:
[...]
super(MyFoo, self).__init__(*args, **kwargs)
TypeError: __init__() got an unexpected keyword argument 'stack'
变像 super(MyFoo, self).__init__(args, kwargs)
结果是:
('Python', 2.7) {'stack': 'overflow'}
I think something is being called here
('Python', 2.7) {'stack': 'overflow'}
出于某些头脑混乱的原因,我对此提出质疑:上面的示例中是对还是错?现实生活中将允许做什么,而在现实生活中不允许做什么?
-
你
Foo.__init__()
不会 不 支持任意关键字参数。您可以添加**kw
其签名以使其接受它们:class Foo(object): def __init__(self, value1, value2, **kw): print 'I think something is being called here' print value1, value2, kw
关键字参数仅与关键字名称完全匹配的参数匹配;您的
Foo
方法将需要具有Python
和stack
关键字参数。如果找不到匹配的关键字参数,但**kw
参数
为 ,则将它们收集在该参数中。如果您的子类知道父类仅具有 位置 参数,则可以随时传递位置:
class MyFoo(Foo): def __init__(self, *args, **kwargs): # do something else, don't care about the args print args, kwargs while len(args) < 2: args += kwargs.popitem() super(MyFoo, self).__init__(*args[:2])
现在您 必须 在其中传递两个或多个参数才能
MyFoo
使调用正常工作。本质上,
super().methodname
返回对bound方法的引用;从那里开始,这是一个 普通 方法,因此您需要传入 任何
方法都可以接受的参数。如果您的方法不接受关键字参数,则会出现异常。