2017-02-23 69 views
0

我正在尝试使用* args来调用该方法的不同方法。以下是我的代码片。了解TypeError:获得关键字参数的多个值

def total(name, *args): 
    if args: 
     print("%s has total money of Rs %d/- " %(name, sum(args))) 
    else: 
     print("%s's piggy bank has no money" %name) 

现在有两种方法可以调用此方法。一个是在*()内传递额外的参数或者用逗号直接分隔。我故意将param = value形式的'name'值传递给它,以致它引发错误。以下是两种方法,我想: -

1 - 薪火额外参数逗号分隔: -

>>> total(name="Adi", 1, 2, 10) 
    File "<stdin>", line 1 
SyntaxError: non-keyword arg after keyword arg 

2 - 使用*()来传递额外参数: -

>>> total(name="Adi", *(1, 2, 10)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: total() got multiple values for keyword argument 'name' 

的第一个错误信息非常清楚,它表达了确切的错误。但是,我无法理解第二次调用的错误消息。

Python如何评估第二次调用它获取参数'name'的多个值?即来到我的脑海的可能途径是内部的Python会被翻译

total(name="Adi", *(1, 2, 10))

如下: -

total(*(1, 2, 10), name="Adi")

在这上面的翻译,因为每个位置,“名”获取价值*(1 ,2,10),然后再次获得“阿迪”。因此可以理解多个值的错误。

但是,我不确定,python是否会在内部改变立场?任何关于此的见解都会有所帮助。

+0

'总(名称 - “阿迪”,1,2,10)'是无效的,因为''''符号。你确定你向我们展示了真实的代码吗? –

+0

我的不好。是一个小姐。 –

回答

1

我检查了使用inspect模块的方法。来自inspect模块的getcallargs()方法为您提供了传递值到方法参数的映射。

def total(name, *args): 
    if args: 
     print("%s has total money of Rs %d/- " %(name, sum(args))) 
    else: 
     print("%s's piggy bank has no money" %name) 

#total(name="Adi", *(1, 2, 10)) 
# equivalent call using inspect module 
import inspect 
print inspect.getcallargs(total, 'Adi', *(1, 2, 10)) 

所以,当一个方法调用时,传递的所有参数变为在以下任一两种形式

*positional :- a tuple of all positional arguments (without keyword) and arguments passed within *() or the extra non-keyworded arguments

**named :- a dictionary of all the arguments passed in form of param=value, and extra keyworded arguments

所以在我的电话total(name="Adi", *(1, 2, 10))'positional'元组的值为(1, 2,10)和'named'字典有价值{'name':'Adi'}

然后它将值赋值给参数。在分配过程中,首先分配强制参数。 Python会检查强制参数列表(这里是['name']),并依次赋值来自'positional'元组的值。任何来自元组的值都保留未赋值,被假定为额外的参数(非密钥参数)。

因此参数'name'获得分配给它的值1。剩余的值(即2和10)被假定为额外的参数。

接下来,它会检查该方法的签名中是否包含非密钥参数。如果是这样,那么将'positional'元组中的剩余值分配给相同。所以这里'args'被分配给剩下的值,即(2,10)的元组。

但是,如果在方法签名中没有非关键字参数,并且'positional'元组有一些值仍未分配,则python会抛出错误“方法需要X个参数Y给出”Y大于X.

一旦分配了'positional'的所有值,就会分配'named'字典中的值分配。在这种情况下,解释器首先检查字典中是否存在强制性参数,即在方法调用中是否以<param=value>的形式传递了任何强制性参数的值?如果是,那么接下来会检查在赋值'positional'元组期间是否已将任何值分配给这些强制参数?

如果是这样,那么它找到相同参数的两个值(一个来自'positional',另一个来自'named'),因此会抛出"got multiple values for keyword argument"错误。否则,它将该值分配给'named'字典中的参数。

以这种方式,在上述情况下,自变量'name'是强制性参数,并且存在于'named'字典中,因为我在方法调用中通过了name="Adi"。在分配位置值(来自'positional'元组的值)期间,变量'name'已经分配了值1。从命名参数字典(值从'named'字典),它的值为'Adi',这使得2个值分配给变量'name'。因此,我们所得到的错误: -

total() got multiple values for keyword argument 'name'

因此,当通过非keyworded额外的参数,需要你只需要把这个值必须的参数,这将使它的位置。但是,不以<param=val>的形式,这将使其命名,并将获得参数的两个值,因此会抛出错误。因此不建议以<param = value >的形式通过必要的参数。

因此正确的方式来调用该方法包括: -

total('Adi', *(1,2,10))

total('Adi', 1, 2, 10)

相关问题