python - 这个函数变量如何持续到 Python 中的下一次调用?
问题描述
如果我运行这段代码,我希望看到 [0] 返回两次。相反,我看到 [0,1]。
def append(flist=[]):
# append the length of a list to the list
flist.append(len(flist))
return flist
print(append())
print(append())
为什么会这样?不应该因为范围而重置表达式吗?如果 flist 存在于函数之外,我如何访问它?
此示例来自https://www.toptal.com/python#hiring-guide关于问题“Q:下面的第二个 append() 语句将打印出什么?”。它确实包含一个简短的解释,但我不明白这是怎么可能的。我能想到的任何分析记忆的东西都没有向我展示这些值,但我也不确定什么是正确的工具来解决这个问题。查看诸如 locals() 或 dir() 之类的东西似乎没有任何意义。
解决方案
如果您尝试这样做,像 PyCharm 这样的编辑器实际上会警告您。
Pycharm 说:“默认参数值是可变的。”
这就是问题所在:您提供的默认值(空列表)是一个实际列表,并且像任何其他列表一样,您可以更改它,如果多个变量将该列表作为值,这些更改将显示在所有他们。
因此,要修复该代码(并获得您想要的行为),您可以这样做:
def append(flist=None):
# initialise if needed
if flist is None:
flist = []
# append the length of a list to the list
flist.append(len(flist))
return flist
print(append())
print(append())
这为您提供了预期的行为,因为对于两个调用,都没有传递任何列表,所以 flist 是 None 并且在每次传递时都分配一个新的空列表,而不是两次传递初始默认列表(第一次运行时为空,包含0
在第二个)。
正如原始问题中所建议的那样,该功能的范围append
不会持续存在。相反,默认值与函数定义存在于同一范围内。因此,在这种情况下,在全局范围内。
每当调用该函数时,这个全局定义的列表就会被修改,这就是为什么这个预期范围为函数的值仍然存在的原因。
推荐阅读
- java - 执行 .sql 脚本文件的 ProcessBuilder 挂起
- spring - Spring Boot - 如何在没有会话存储的情况下永久保留 JSESSIONID
- ng-bootstrap - 如何计算数据之间的差异或比较(是否更大)(Jalali 日历)
- python-3.x - 如何在 ubuntu 上使用 cmake 在 python 虚拟环境(conda)中构建和安装 flann 和其他库
- datagridview - 如果 C# datagridview 行求和
- .net - vb.net, Xtrareport :如何在 Xrtable 扩展的每个页面上显示 Xrtable 的标题?
- dns - DNS 从 Godaddy 更改为 Netlify
- excel - 使用VBA查找段落中文本的位置
- android - Firebase getValue 以 HasMap 的形式返回,无论我如何要求它
- python - Detectmultiscale() 有时会返回一个空元组