【问题标题】:Python Default Arguments Evaluation [duplicate]Python默认参数评估[重复]
【发布时间】:2015-09-01 08:18:29
【问题描述】:

我正在阅读 Python Documentation Release 2.7.10 中的 python 教程,我遇到了类似这样的内容。

代码

def fun1(a,L=[]):
    L.append(a)
    return L

print fun1(1)
print fun1(2)
print fun1(3)

def fun2(a,L = None):
    if L is None:
        L=[]
    L.append(a)
    return L

print fun2(1)
print fun2(2)
print fun2(3)

输出

[1]
[1, 2]
[1, 2, 3]
[1]
[2]
[3]

Process finished with exit code 0

如果第一个函数fun1() 中的L=[] 只被调用一次,则fun1() 的输出很好。但是为什么L=None 每次都在fun2() 中被调用。

【问题讨论】:

  • “为什么L=None 每次都没有被调用” – 我不知道你想说什么。
  • 我假设 L=None 每次都被调用/执行。这就是为什么条件if L is None 在第二个函数fun2() 中每次都为真。
  • 默认参数在函数声明时进行评估。空列表是可变的,因此在每个函数调用中您都在编辑相同的列表。附加到它不会创建新对象。使用 None 时,在函数体中创建列表。每次从函数返回新列表。

标签: python python-2.7 arguments default-arguments


【解决方案1】:

函数声明中的L=[]使得Python本质上是这样做的:

  • 这个函数有一个名为L的参数
  • 它的默认参数是[],让我们把这个特殊的[]放在一边,并在没有为L传递参数的任何时候使用它
  • 每次调用函数时,创建一个变量L,并为其分配传递的参数或我们之前预留的值

所以,[] 部分被执行一次,它创建了一个列表对象,该对象被搁置并保留,这就是为什么如果你修改它会累积更改。 None 也发生了完全相同的事情,但是 None 没有被修改,也不是一开始就可变的,所以你没有看到任何奇怪的副作用。 None 仍然只被“执行”一次,并且那个特定的 None 值就像列表一样被搁置,只是你没有对 None 值本身做任何事情。

【讨论】:

  • 但我正在将fun2() 中的if 条件内的L=None 更改为L=[]。为什么此分配/更改不是永久的或对其他后续函数调用不可见。
  • 再次重申:每次调用函数时,都会创建变量 L 并为其赋值[] 是永久的,而不是它与L 的关联。 [] 存储您 .append 的内容,而不是 L。内存中的永久对象[] 与指向它的变量L 不同。
【解决方案2】:

当你定义一个函数时,默认参数的值会被评估,但是函数的主体只会被编译。您可以通过属性检查函数定义的结果。有一个 __defaults__ 属性包含默认值,__code__ 属性包含正文(因此这些是在定义函数时创建的)。

第二个示例中发生的情况是 None 确实在定义时被评估(它评估为 None duh!),但有条件地将 [] 分配给 L 的代码只会被编译并运行每个时间(条件通过)。

【讨论】:

    【解决方案3】:

    默认参数只计算一次。在fun1 中,您拥有不断添加的相同列表。在fun2 中,您将新的[] 分配给参数,然后附加到它。与任何assignment一样,它的范围将被限制在它发生的区块内。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-19
      • 2019-09-20
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      • 2010-12-11
      • 2011-08-05
      相关资源
      最近更新 更多