python 函数的默认值参数会针对列表进行缓存,但不会针对其他类型进行缓存

标签 python

下面的代码按照它的方式工作,因为列表“b”在定义时被缓存并重用,除非调用点传递一个特定值来为该特定调用初始化一个新列表。

>>> def app(a,b=[]):
...     if a==1:
...         b.append(a)
...    print b
... 
>>> app(1)
[1]
>>> app(1)
[1, 1]
>>> app(1)
[1, 1, 1]

但是相同的行为不适用于非列表类型的参数,为什么?

>>> def stri(a,b=""):
...    b=b+a
...    return b
... 
>>> stri("a")
'a'
>>> stri("a")
'a'
>>> stri("a")
'a'

>>> def app(a,b=0):
...   if a==1:
...     b=a+b
...   print b
... 
>>> app(1)
1
>>> app(1)

最佳答案

因为字符串是不可变的(无法就地更改),而列表则不然。您将在第一种情况下附加到默认参数,并在第二种情况下修改变量指向的内容。

举例说明:

>>> def app(a, b=[]):
...     b = b + [a]
...     print(b)
...
>>> app(0)
[0]
>>> app(1)
[1]
>>> app(2)
[2]
>>>

(请注意,+= 实际上也会就地更改 list,因此它在语义上与赋值不同)

如果您希望每次调用都有一个新的列表,请执行以下操作:

def f(a=None):
    if a is None:
        a = []
    ...

或者这个:

def f(a=None):
    a = a or []
    ...

关于python 函数的默认值参数会针对列表进行缓存,但不会针对其他类型进行缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55272261/

相关文章:

python - 找不到正确的字符串结尾

python - Python 中的 read() 和 read1() 有什么区别?

python - 如何在 GAE for Python 上获取 Model() 中条目的 key_name?

python - 如何仅通过命令行在虚拟机中启动并运行服务器?

python - scikit-learn GridSearchCV best_score_ 是如何计算的?

python - numpy 中所有可能的列乘法?

python - 这个python程序有什么错误?

python - 类和数组问题

python - 以下 lambda 函数如何代替 Python 排序函数中的 'itemgetter'?

python - 尝试在 2.7 版上安装 Ipython 但它一直尝试在 2.5 版上安装