仍然对 Python 中的可变默认参数值“陷阱”感到困惑[重复]

2023-11-21

我知道不应该使用可变的默认参数值在 Python 中(有一些例外),因为该值仅在定义函数时计算和存储一次,而不是在以后每次调用函数时计算和存储。

我对此的理解是这样的(使用下面的例子;请原谅我的不精确的语言,因为我只是Python编程的初学者,因此陷入了我教科书的“函数”章节):

def f(x = [1, 2, 3]):
    x.append(4)
    print(x)

f()
f()

1) 定义了函数 f,并且 x(f 中的局部变量)采用默认变量 [1, 2, 3](甚至在调用函数之前)

2) 当调用 f() 时,由于没有参数传递给 x,x 仍然是 [1, 2, 3],并且 x 继续具有其默认值

3) x 通过append 就地修改,变成[1, 2, 3, 4],并按原样打印

然而,这就是我困惑的地方。我假设:

4) 当 f 结束时,x 被销毁(在堆栈中或无论你如何称呼它)并且不再与列表对象 [1, 2, 3, 4]** 关联

5) 列表对象 [1, 2, 3, 4] 被回收,因为不再有变量引用它

所以,

6) 当第二次调用 f() 时,我希望 Python 输出一个错误,因为 x 现在不再有与之关联的值。换句话说,当 Python 被回收/销毁时,如何重用上次评估的默认值?

感谢您的所有帮助和解释!

** this understanding I got from Ned Batchelder's page on variable name assignment (see below) Net Batchelder's variable assignment function


虽然您可能认为在执行结束时 x(默认值)已被释放,但事实并非如此。

事实上,Python 有一个全局命名空间,其中包含可供您使用的所有名称(内置函数、您导入或定义的类和函数)。

该命名空间的内容由对象组成。函数也是对象。

作为测试,如果您在脚本或 python 命令行中尝试此操作,您就会明白我的意思:

def f(x = [1, 2, 3]):
    x.append(4)
    print(x)
print dir(f)

您将看到函数 f 的对象性质。作为对象,默认值在属性中引用,f.func_defaults,因此它们始终可用,如果可变,它们会保留更改,从而给您带来可能不想要的副作用。

编辑:在 python 3 中,该属性已被替换为f.__defaults__

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

仍然对 Python 中的可变默认参数值“陷阱”感到困惑[重复] 的相关文章

随机推荐

  • 没有给出与所需的形式参数“选项”相对应的参数

    我正在 Net Core 中开发我的第一个应用程序 由于某种原因 我收到此构建错误 错误CS7036没有给出与 LakeViewContext LakeViewContext DbContextOptions LakeView所需的形式参数
  • SQL Server 奇怪的多列分组场景和 OR

    我有一个奇怪的分组场景 并且在找出 SQL 中分组的最佳方法时遇到了一些麻烦 假设我们有下面一张表 CREATE TABLE Item KeyId VARCHAR 1 NOT NULL Col1 INT NULL Col2 INT NULL
  • java.lang.OutOfMemoryError:位图大小超出 VM 预算 - Android

    我在 Android 上开发了一个使用大量图像的应用程序 该应用程序运行一次 填充屏幕上的信息 Layouts Listviews Textviews ImageViews等 用户读取信息 没有动画 没有特效或者任何可以填满记忆的东西 有时
  • TabBarItems 并设置它们的图像大小?

    我目前正在向我的每个选项卡栏项目添加图像 我喜欢的一张图像的尺寸比条形项目的面积大得多 当我在故事板中设置栏项目的图像并运行模拟器时 带有该图像的栏按钮覆盖整个屏幕 现在我认为有一些自动方法可以让图像为每个栏按钮调整大小 遗憾的是事实并非如
  • 如何从航路 3 直接升级到航路 5

    开发由许多客户在许多生产环境中部署的产品 它至少包含一个 Spring Boot 应用程序 我们使用 Flyway 进行数据库模式迁移 从 Spring Boot 1 5 x 升级到 2 0 x 使我们的 Flyway 版本从 3 x 升级
  • InflateException 与来自官方设计库的 FloatingActionButton

    我在使用官方的时候遇到了一个bugFloatingActionButton来自 Google 的支持设计库 这是我的 LogCat android view InflateException Binary XML file line 34
  • 如何加快 Gensim Word2vec 模型加载时间?

    我正在构建一个聊天机器人 因此需要使用 Word2Vec 对用户的输入进行矢量化 我正在使用 Google 提供的包含 300 万个单词的预训练模型 GoogleNews vectors male300 所以我使用 Gensim 加载模型
  • 在 CMake 中获取目标依赖的所有源文件

    使用 CMake 如何获取进入可执行目标的所有源文件的列表 包括该可执行文件所依赖的所有目标中的所有源 我们在代码库中有一个模式 其中构建系统根据源树中的文件名和路径生成初始化程序调用程序 因此 我需要可执行目标所依赖的所有源文件的完整路径
  • Android - 如何使用新的存储访问框架将文件复制到外部 SD 卡

    我正在我的应用程序中实现文件浏览器功能 我知道如何使用 ACTION OPEN DOCUMENT TREE 意图获得外部 SD 卡的持久权限 以及如何使用 DocumentFile 类创建文件夹和删除文件 文件夹 但是 我无法找到将文件复制
  • 编译 ng-bind-html 后 ng-click 不起作用

    我有一个指令 app directive dir function compile sce return restrict E link function scope element attr scope watch content fun
  • 如何删除Python中的标点符号?

    我有一个问题 前任 我有一句话 s AAA BBB CCC 所以 我这样做 import string table str maketrans string punctuation s w translate table for w in
  • 公开受保护字段的最佳方式

    我有一个像这样的基类 public class BaseModalCommand protected object m commandArgument protected int m commandID protected int m en
  • 暂停脚本执行的 jQuery 确认框

    我正在寻找一个 jquery 漂亮的标准对话框替代品 jQUery UI 有一个很好的功能 但它不会像confirm 那样暂停脚本执行以等待响应 下面的演示应该显示两个 div 显示前面确认框的选择 但 jquery 对话框不会导致脚本等待
  • 如何让子模块触发 Jenkins 构建

    我有一个子模块 A 它不是独立的应用程序 它需要主应用程序才能工作 我想为 A 创建一个 CI 构建 以便每当将提交推送到 A 时 它都会触发使用主项目代码的构建 我该如何在詹金斯中做到这一点 我需要做什么 对 A 的提交会触发构建 该构建
  • Code Golf:重复文本的“颜色突出显示”

    Locked 这个问题及其答案是locked因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 感谢下面的 greg0ire 帮助理解关键概念 挑战 构建一个程序来查找所有子字符串并使用颜色属性 标记 它们 在 XML 中有效
  • 将单个 Excel 工作表另存为 CSV

    我需要解析 Excel 工作表 现在 我将每个单独的工作表另存为 csv 效果非常好 我使用 OpenCSV 来解析文件等 但创建这些 csv 文件很痛苦 在 Excel 中将单个工作表另存为 csv 的最简单 最快捷的方法是什么 我假设某
  • 使用 Shadow DOM 有哪些缺点?

    在教程中我只看到了 Shadow DOM 的优点 但也应该有缺点 在哪些情况下我们应该避免使用 Shadow DOM Shadow DOM 功能既可以被视为优点 也可以被视为缺点 风格隔离如果您想要的话 这是一个好处 但如果用户想从全局 C
  • 从预处理器中的常量中删除强制转换

    背景 在微控制器代码中 我使用生产商提供的库 其中定义了许多常量 如果我的一些常量 与微控制器外部的组件共享 与git subtree 和微控制器常数 例如 该库定义 ifdef SOME PARTICULAR MODEL define F
  • SSRS 2008 R2 - SSRS 2012 - ReportViewer:在 Safari/Chrome 中报告,但在 Firefox/Internet Explorer 8 中工作正常...为什么?

    我有一些简单的报告SSRS 2008 R2 但它们根本不会在 Safari 或 Chrome 中显示 根据微软的在线图书 这些浏览器的支持方式有限 但是 数据 加载 时钟完成后我看不到任何内容 页面顶部的参数栏和面包屑导航部分都在那里 此外
  • 仍然对 Python 中的可变默认参数值“陷阱”感到困惑[重复]

    这个问题在这里已经有答案了 我知道不应该使用可变的默认参数值在 Python 中 有一些例外 因为该值仅在定义函数时计算和存储一次 而不是在以后每次调用函数时计算和存储 我对此的理解是这样的 使用下面的例子 请原谅我的不精确的语言 因为我只