简体   繁体   English

__init __()为关键字参数“ bar”获得了多个值

[英]__init__() got multiple values for keyword argument 'bar'

What seems like a simple pattern for allowing a variable number of positional arguments along with a defaulted named arg doesn't work. 看起来像一个简单的模式,它不允许可变数量的位置参数以及默认名称的arg起作用。 I think I can overcome this by using **kwargs , but is there something more straightforward I am doing wrong? 我想我可以通过使用**kwargs来克服这个问题,但是我做错了什么更直接的方法吗?

Why doesn't this work? 为什么不起作用?

class Foo(obect):
    """Baffling"""
    def __init__(self, bar=None, *args):
        pass

foo = Foo(1) #works
foo = Foo(1, bar=2) # explodes

----> 1 foo = Foo(1, bar='baz')
TypeError: __init__() got multiple values for keyword argument 'bar'

How is the above code passing a duplicate bar keyword argument? 上面的代码如何传递重复的bar关键字参数?

In Python, named attributes are used after non-named (like *args ). 在Python中,已命名属性在未命名之后使用(例如*args )。 So you should change your __init__ as: 因此,您应将__init__更改为:

def __init__(self, *args, bar=None):

Here is the example: 这是示例:

class Foo(object):
    """Baffling"""
    def __init__(self, *args, bar=None):
        self.bar = bar

foo = Foo(1, bar=2) # explodes
foo.bar

Will return: 将返回:

Out[...]: 2


PS Anyway it is not a good idea to mix *args , **kwargs and named attributes. PS无论如何,混合*args**kwargs和命名属性不是一个好主意。 I recommend you to avoid it. 我建议您避免这种情况。

Named arguments can be passed both by position and by name: 命名参数既可以按位置也可以按名称传递:

>>> def foo(a):
...     print(a)
...
>>> foo(1)
1
>>> foo(a=2)
2

If you pass positional and keyword arguments, they get assigned in order. 如果您传递位置和关键字参数,则会按顺序分配它们。 In your case, 1 gets assigned to the first positional argument ( bar ), then bar=2 assigns the the argument named bar . 在您的情况下,将1分配给第一个位置参数( bar ),然后bar=2分配名为bar的参数。 Thus, both assign to the name bar , creating a conflict. 因此,两者都分配给名称bar ,从而产生冲突。


You can pass additional arguments after your named one: 您可以命名的参数之后传递其他参数:

>>> def foo(bar=None, *args):
...    print('args=%r, bar=%r' % (args, bar))
...
... foo(2, 1)  # bar=2, *args=(1,)
args=(1,), bar=2

In Python3, you can also make your parameter keyword only: 在Python3中,您还可以仅将parameter关键字设置为:

>>> def foo(*args, bar=None):
...    print('args=%r, bar=%r' % (args, bar))
...
... foo(1, bar=2)
args=(1,), bar=2

This also works when you do not take any variadic arguments: 当您不接受任何可变参数时,这也适用:

>>> def foo(*, bar=None):
...    print('args=%r, bar=%r' % ('undefined', bar))
...
... foo(bar=2)
args='undefined', bar=2
>>> foo(1, bar=2)
TypeError: foo() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given

In Python2, only **kwargs is allowed after *args . 在Python2中,在*args之后仅允许**kwargs You can emulate named parameters by popping them from kwargs : 您可以通过从kwargs弹出命名参数来模拟它们:

>>> def foo(*args, **kwargs):
...    bar = kwargs.pop("bar")
...    print('args=%r, bar=%r' % (args, bar))
...
... foo(1, bar=2)
args=(1,), bar=2

If you want named-only parameters without variadic positional and named parameters, you must raise errors yourself: 如果您想要不带可变参数位置和命名参数的仅命名参数,则必须自己引发错误:

>>> def foo(*args, **kwargs):
...    bar = kwargs.pop('bar')
...    if args or kwargs:
...        raise TypeError
...    print('args=%r, bar=%r' % ('undefined', bar))
...
... foo(bar=2)
args='undefined', bar=2
>>> foo(1, bar=2)
TypeError

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 __init__() 为关键字参数“列”获得了多个值 - __init__() got multiple values for keyword argument 'columns' TypeError:__init __()为关键字参数“ choices”获得了多个值 - TypeError: __init__() got multiple values for keyword argument 'choices' windrose:__init __()获得了多个关键字参数值 - windrose: __init__() got multiple values for keyword argument TypeError:“ __ init __()为关键字参数'name'获得了多个值” - TypeError: “__init__() got multiple values for keyword argument 'name'” __init __()为关键字参数'input_formats'获得了多个值 - __init__() got multiple values for keyword argument 'input_formats' TypeError:__ init __()得到关键字参数'customer'的多个值 - TypeError: __init__() got multiple values for keyword argument 'customer' __init__() 为参数“crescator”获得了多个值 - __init__() got multiple values for argument 'crescator' __init__() 为参数“填充”获得了多个值 - __init__() got multiple values for argument 'padding' 在Scrapy中使用规则和请求会引发异常TypeError:__init __()为关键字参数'callback'获得了多个值 - Using Rules and Requests in Scrapy throws exception TypeError: __init__() got multiple values for keyword argument 'callback' / __init __()的Django Rest Framework TypeError为关键字参数'read_only'获取了多个值 - Django Rest Framework TypeError at / __init__() got multiple values for keyword argument 'read_only'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM