我检查了使用的方法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) )
因此,当调用方法时,传递的所有参数都采用以下两种形式之一
*位置:- 所有位置参数(不带关键字)和 *() 内传递的参数或额外的非关键字参数的元组
**named :- 以 param=value 形式传递的所有参数的字典,以及额外的关键字参数
所以在我的通话中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'
tuple?
如果是这样,那么它会为同一参数找到两个值(其中一个来自'positional'
另一个来自'named'
),因此抛出"got multiple values for keyword argument"
错误。否则,它将值分配给来自'named'
字典。
这样,在上述情况下,论证'name'
是强制论证并且存在于'named'
我已经通过的字典name="Adi"
在方法调用中。在分配位置值期间(值来自'positional'
元组),变量'name'
已获得分配给它的值 1。并来自命名参数字典(来自的值'named'
字典),它的值是“Adi”,这使得 2 个值被分配给变量'name'
。因此我们收到错误:-
Total() 获得关键字参数“name”的多个值
因此,在传递非关键字额外参数时,只需传递强制参数的值,这将使其成为位置参数。但是,不是以<param=val>
,这将使其命名并获得参数的两个值,因此将引发错误。因此,不建议以以下形式通过强制论证:<param = value >
.
所以调用该方法的正确方法是:-
总计('阿迪', *(1,2,10))
or
总计('阿迪', 1, 2, 10)