python - 具有默认值的 Python defaultdict 类实例化
问题描述
当 defaultdict 配置为实例化一个类时,如果该类具有默认参数,则行为会有所不同。
例如,这是预期的行为:
from typing import List
from collections import defaultdict
class Test:
def __init__(self):
self.values = []
tests = defaultdict(Test)
tests['a'].values.append(1)
tests['b'].values.append(2)
print([f"{id}: {t.values}" for id, t in tests.items()]) #--> ['a: [1]', 'b: [2]']
现在,当类具有默认值时,所有对象共享相同的引用:
class Test:
def __init__(self, values = []):
self.values = values
tests = defaultdict(Test)
tests['a'].values.append(1)
tests['b'].values.append(2)
print([f"{id}: {t.values}" for id, t in tests.items()]) #--> ['a: [1, 2]', 'b: [1, 2]']
仅当参数是引用时才会发生这种情况,例如:
class Test:
def __init__(self, values = 0):
self.values = values
tests = defaultdict(Test)
tests['a'].values += 1
tests['b'].values += 1
print([f"{id}: {t.values}" for id, t in tests.items()]) #--> ['a: 1', 'b: 1']
这是为什么?
解决方案
发生这种情况是因为在定义函数时会精确评估一次默认值,而不是每次调用它时。
https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
为了澄清,python中的所有变量都是引用。只是他们所指的有些东西是可变的,有些则不是。
推荐阅读
- php - 当全局变量在 PHP 中不存在时,为什么可以在函数中使用 global 关键字?
- c# - 在 iOS 中测试 Xamarin.Forms 应用程序时出现 System.ArgumentOutOfRangeException
- javascript - 打开加载外部 HTML 的模态对话框后覆盖 CSS
- java - 如何通过 POSTMAN 或 Swagger UI 将 org.springframework.util.MultiValueMap 中的多个参数作为标题传递
- php - PHPmailer 突然停止从本地主机或服务器 AWS 发送电子邮件
- html - 如何使用 jquery 将类添加或附加到最后一个 li 元素
- c++ - 如何从单个 C++ return 语句中返回多个值中的一个?
- windows - Vagrant up 命令错误“执行 `VBoxManage 时出错”
- f# - F# 和邮箱处理器不执行
- python - 如何通过 Paramiko 获取广播消息