为什么不能在子类的init中传递*args和**kwargs

2024-06-16 12:56:02 发布

您现在位置:Python中文网/ 问答频道 /正文

为了理解“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'}

出于一些令人震惊的原因,我质疑这个问题:在上面的例子中,什么是对的,什么是错的?在现实生活中,什么是可以做的,什么是不可以做的?


Tags: theselffooinitdefargsdosomething
3条回答

原因是所有的论点都已经被解压成了夸尔格,现在是一个格言。你试图把它传递给一个正态变量。

def bun(args,kwargs):
print 'i am here'
print kwargs

def fun(*args,**kwargs):
print kwargs
bun(*args,**kwargs)

 fun(hill=3,bi=9) # will fail.


def bun(*args,**kwargs):
print 'i am here'
print kwargs

def fun(*args,**kwargs):
print kwargs
bun(*args,**kwargs) # will work.



fun(hill=3,bi=9)

尝试在处进行修改

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'

应该有用的。。!

您的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方法需要有Pythonstack关键字参数。如果没有找到匹配的关键字参数,但是**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返回对绑定方法的引用;从那时起,它就是一个normal方法,因此需要传入任何方法都可以接受的参数。如果方法不接受关键字参数,则会出现异常。

当您这样做时:

super(MyFoo, self).__init__(*args, **kwargs)

这与您所做的相同,基于代码的工作方式:

super(MyFoo, self).__init__("python", 2.7, stack="overflow")

但是,Foo__init__函数(从中继承MyFoo)不支持名为“stack”的关键字参数。

相关问题 更多 >