在Python中,为什么函数参数在函数调用之间保持其值

时间:2018-01-28 09:54:06

标签: python

我在Python方面相当新,我无法理解我的结果 使用以下代码:

def func(a,b=set()):
    res=list()
    for i in a:
        if i not in b:
            res.append(i)
            b|={i}
    return res

print(func([1,1,2,2,3,4]))
print(func([1,1,2,2,3,4]))

我得到了输出:

[1,2,3,4]
[]

我把" print(b)"以上" res = list()"得到了输出:

set()
[1,2,3,4]
{1,2,3,4}
[]

发生了什么事?不应该" b"设置为" set()"当我打电话给这个功能?我使用的是Python 3.6

3 个答案:

答案 0 :(得分:4)

查看documentation的默认参数:

  

默认值仅评估一次。当默认值是可变对象(如列表,字典或大多数类的实例)时,这会有所不同。

使用默认参数定义函数时,仅在解释器首次执行定义时才会计算默认值(实际的def语句)。这通常不是问题,除非使用可变的默认值。也就是说,可以对其进行修改。

在您的情况下,当您第一次调用函数时修改函数中的b时,它会在下次保留该值。为避免这种情况,您可以这样做:

def func(a,b=None):
    if b is None:
        b = set()
    res=list()
    for i in a:
        if i not in b:
            res.append(i)
            b|={i}
    return res

现在b将始终具有您想要的默认值。

答案 1 :(得分:2)

在python函数中,对象和参数被评估并执行一次。这是一个很好的解释:http://effbot.org/zone/default-values.htm

在您的示例中,可以通过执行以下操作来“修复”:

def func(a,b=None):
    if b is None:
        b = set()
    res=list()
    for i in a:
        if i not in b:
            res.append(i)
            b|={i}
    return res

答案 2 :(得分:1)

在第一个函数中,调用b为空 见这里

enter image description here

在第二个函数中,调用b已经填充了元素 enter image description here

因此,此条件不会运行if i not in b并返回空列表

试试这个

def func(a):
    res=list()
    b=set()
    for i in a:
        if i not in b:
            res.append(i)
            b|={i}
    return res

print(func([1,1,2,2,3,4]))
print(func([1,1,2,2,3,4]))

输出

  

[1,2,3,4]

     

[1,2,3,4]