Python默认参数和参数名称

时间:2012-01-21 05:55:42

标签: python

我想知道'a = a'和'b = b'是否会导致问题/意外行为?代码在示例中工作正常。

def add_func(a=2,b=3):
   return a+b

a=4
b=5
answer = add_func(a=a, b=b)

由于

2 个答案:

答案 0 :(得分:5)

虽然我很想被证明是错的,但并不是我所知道的。

正式语言参考定义the lexical structure of a function call。重要的是它将“keyword_item”定义为identifier "=" expression。此外,这里是关于如何解释调用的参数的说法:

  

如果存在关键字参数,则首先将它们转换为   位置参数如下。首先,未填充的插槽列表是   为形式参数创建。如果有N位置   参数,它们被放置在前N个槽中。接下来,每个   关键字参数,标识符用于确定   相应的槽(如果标识符与第一个正式的相同)   参数名称,使用第一个插槽,等等)。如果插槽是   已填充,引发TypeError异常。否则,价值   将参数放在槽中,填充它(即使是   表达式为None,它填充插槽)。当所有论据都是   处理完毕后,尚未填充的插槽将被填充   函数定义中相应的默认值。

列出了一些可能的情况。

在简单的情况下,就像你提到的那样,有两个正式参数(ab),如果你使用像add_func(a=a, b=b)这样的关键字参数指定函数调用,这里是会发生什么:

  1. 创建两个插槽来保存参数。
  2. 由于您未在调用中提供任何位置参数(只是关键字参数),因此最初都不会填充任何插槽。
  3. 分别对每个关键字参数进行分析,并将参数的标识符a=部分中的“a”)与所有形式参数名称进行比较。 function(定义函数时给出参数的名称,在我们的例子中为ab)。
  4. 当匹配发生时,关键字参数的(在本例中为4!)用于填充相应的广告位。
  5. 重复此操作直到分析所有关键字参数。如果未填充所有插槽,则Python会尝试为其余插槽分配默认值(如果存在)。如果没有,则会引发错误。
  6. 因此,Python完全区别对待关键字参数中的“标识符”。但这仅适用于关键字参数;很明显,如果您尝试add_func(b, a)之类的内容,即使您的参数本身被称为ba,这也不会将 映射到其中的形式参数功能;你的参数会倒退。但是,add_func(b=b, a=a)工作正常;只要它们是关键字参数,这些位置无关紧要。

答案 1 :(得分:0)

这取决于指向的全局对象是可变的还是不可变的。不可变对象(如整数)在修改时是副本,因此它是安全的。诸如列表之类的可变对象是就地修改的,并且使用这种方式是不安全的。对它们的任何更改都会在调用之间持续存在,并且可能(并且可能会)导致意外行为。

此:

a=[]
def f(a=a):
    pass

与:

相同
def f(a=[]):
    pass

这是Python程序中一种已知的不良做法。