Python中的默认参数是静态的吗?

时间:2019-04-13 15:58:17

标签: python parameters static default

作为C ++程序员,我在Python中遇到了意外的行为。在下面的示例中,输出为:

Metalsmith(__dirname)
  .source('./contents')
  .destination('./build')
  .clean(true)
  .use(inPlace()) // inPlace must come BEFORE layouts!
  .use(layouts({
    directory: '_layouts',
    default: 'base.njk'
  }))
  .build(function(err) {
    if (err) throw err;
  });

但是我本来希望得到这样的输出:

y:A1
A1
B1

我使用python 2.7。对于我来说,令人惊讶的是,在函数的第二次调用中,默认参数已经具有上一次调用的结果中的值。它应该不是一个空列表吗?

这是python代码:

B1

编辑: 正如其他人所指出的,这个问题是重复的。简短的答案是python在程序启动时仅评估一次默认参数,并将结果静态存储在函数中。从C ++,我希望每次调用该函数并仅在本地而不是静态存储该函数时都会对其进行评估。

在我的代码中,我看到这种行为有两种危险情况: A)函数应修改一个列表,但如果在函数调用时未传递参数,则该列表应以一个空列表开头。现在我有一个问题,就是这个名单越来越多。

解决方案是 a)删除参数的默认值,以使我至少被迫提供一个空列表:

def f( x, y=[]):
    for z in y:
        print "y:" + str(z)
    result = y   
    result.append(x+'1')
    return result

l = f('A') 
l = f('B')

for x in l:
    print x 

b)使用“无”作为默认参数:

def f( x, y):
    result = y
    result.append(x+'1')
    return result

l = f('A',[]) 
l = f('B',[])

B)另一个问题是默认参数是在程序启动时计算的,我现在使用时间戳作为默认参数...

1 个答案:

答案 0 :(得分:0)

result = y使得名称resulty指向内存中的同一对象,因此第二个调用中的列表y将不会为空(因为现在任何对result的修改也将出现在y中(如果您要追加),请尝试此操作(列表切片),它将为您提供所需的输出:

result = y[:] # elements of y, from the first to the last

此切片的值等效于result = y,但是resulty将指向内存中的两个不同对象,因为切片会创建一个新列表。