Python方法采用一个位置参数,但给出了两个

时间:2017-07-31 12:25:13

标签: python function dictionary keyword-argument

我遇到了一个我不太明白的错误。如果我有以下代码段:

class Test(object):
  def __init__(self):
    self.data = {}

  def update_data(self, **update):
    self.data = update

t = Test()

t.update_data(test='data') #  Works
t.update_data({'test':'data'}) #  TypeError: update_data() takes 1 positional argument but 2 were given

因此,根据我的理解,**update语法是字典破坏语法,当您将dict传递给函数时,它会转换为关键字参数。

我在这里不正确地理解了什么?

2 个答案:

答案 0 :(得分:8)

如果您只是传入字典,它将被视为任何其他变量。在你的情况下,你作为位置参数传递它,因此它将被视为位置参数。但是,该方法不接受任何位置参数(self除外,但这是另一个故事),因此它会引发错误。

如果您想将字典内容作为关键字参数传递,则需要将其解压缩(**在字典前面):

t.update_data(**{'test':'data'})

如果你想将字典作为字典传入,你也可以将它作为关键字参数传递(然后不进行解包!):

t.update_data(funkw={'test':'data'})

答案 1 :(得分:1)

将关键字参数传递给函数时,它会转换为字典。不是相反。

args和kwargs的详细说明

* args表示函数/方法可以接受任意数量的位置参数,并存储在名为args的列表中。

** kwargs意味着它可以接受任意数量的命名参数,并将存储在名为kwargs的字典中 还不清楚?让我举个例子(尽管非常简单和天真) -

# Suppose you want to write a function that can find the 
# sum of all the numbers passed to it.

def sum(a, b):
    return a + b

>>> sum(2, 3) # => 5

# Now this function can only find sum of two numbers, what 
# if we have 3, 4 or more numbers, how would be go solving that.
# Easy let's take an array/list as an argument -

def sum(numbers):
    total = 0

    for number in numbers:
        total += number

    return total

# But now we'd have to call it like -
>>> sum([2, 3]) # => 5
>>> sum(2, 3) # => throws an error.

# That might be ok for some other programming languages, but not 
# for Python. So python allows you to pass any number of 
# arguments, and it would automatically store them into list 
# called args (as a conventions, but it can be called 
# anything else say 'numbers')

def sum(*numbers):
    total = 0

    for number in numbers:
        total += number

    return total

>>> sum(2, 3, 4) # => 9

# Viola! 

类似地,kwargs用于将所有命名参数自动存储为字典。