我正在尝试使用* args调用方法的不同方法。下面是我的代码片段。
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 - 将额外的params逗号分开: -
>>> 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将翻译
总计(姓名=“Adi”,*(1,2,10))
如下: -
总计(*(1,2,10),name =“Adi”)
在上面的翻译中,根据位置,'name'得到值*(1,2,10),然后再得到“Adi”。因此可以理解多值误差。
但是,我不确定,内部的python是否会改变这些立场?任何有关这方面的见解都会有所帮助。
答案 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) )
因此,当调用方法时,传递的所有参数都采用以下两种形式之一
*位置: - 所有位置参数的元组(没有关键字)和在*()内传递的参数或额外的非密钥参数
**命名: - 以param = value形式传递的所有参数的字典,以及额外的keyworded参数
因此,在我的电话total(name="Adi", *(1, 2, 10) )
中,'positional'
元组有值(1,2,10),'named'
字典有价值{&#39; name&#39;:&#39 ;阿迪&#39;}
然后它将值赋值给参数。在分配期间,首先分配强制参数。 Python检查强制参数列表(这里[&#39; name&#39;])并按顺序分配'positional'
元组的值。来自未分配的元组的任何值都被假定为额外参数(非密钥参数)。
因此参数'name'
获得分配给它的值1。并且剩余的值(即2和10)被假定为额外参数。
接下来,它检查方法是否在其签名中包含非keyworded参数。如果是,则将'positional'
元组的剩余值分配给它们。所以这里'args'
被赋予剩余的值,即(2,10)的元组。
但是,如果方法签名中没有非关键字参数,并且'positional'
元组仍有一些值未分配,那么python会抛出错误&#34;方法需要正确的X参数Y给出&#34 ; Y大于X。
分配'positional'
的所有值后,将分配'named'
字典中的值分配。在这种情况下,解释器首先检查字典中是否存在任何强制参数,即在方法调用中是否以<param=value>
的形式传递任何强制参数的值?如果是,那么接下来它检查在'positional'
元组的值赋值期间是否已为这些强制参数赋值?
如果是这样,那么它会为同一个参数找到两个值(一个来自'positional'
,另一个来自'named'
),因此会抛出"got multiple values for keyword argument"
错误。否则,它会将值分配给'named'
字典中的参数。
以这种方式,在上面的例子中,参数'name'
是强制参数,并且在'named'
字典中出现,因为我在方法调用中已经通过了name="Adi"
。在分配位置值(来自'positional'
元组的值)期间,变量'name'
已获得分配给它的值1。从命名参数的字典(来自'named'
字典的值)中,它具有值&#39; Adi&#39;,它将2个值分配给变量'name'
。因此我们得到错误: -
total()获得了关键字参数&#39; name&#39;
的多个值
因此,在传递非keyworded额外参数时,需要传递强制参数的值,这将使其成为位置。但是,不是<param=val>
的形式,它将使它命名并将获得参数的两个值,因此将抛出错误。因此,不建议以<param = value >
的形式传递强制参数。
因此调用该方法的正确方法是: -
总计(&#39; Adi&#39;,*(1,2,10))
或
总计(&#39; Adi&#39;,1,2,10)