【问题标题】:Scope of variable within "with" statement?“with”语句中的变量范围?
【发布时间】:2020-11-09 00:10:25
【问题描述】:

我正在使用 python 读取 firstline

with open(file_path, 'r') as f:
    my_count = f.readline()
print(my_count)

我对变量 my_count 的范围有点困惑。虽然打印工作正常,但最好先在外面做 my_count = 0 之类的事情(例如在 C in 中用来做 int my_count = 0

【问题讨论】:

  • 我在提供的代码中没有看到logs_count。你的意思是my_count
  • 那段代码没问题,不需要在python循环外初始化my_count

标签: python scope with-statement


【解决方案1】:

with 语句不创建范围(如 ifforwhile 也不创建范围)。

因此,Python 将分析代码并查看您在 with 语句中进行了赋值,因此这将使变量成为本地变量(在实际范围内)。

在 Python 中,变量不需要在所有代码路径初始化:作为程序员,您有责任确保在使用变量之前对其进行赋值。这可能会导致代码更短:例如,您确定一个列表包含至少一个元素,然后您可以在 for 循环中分配。在 Java 中,for 循环中的赋值被认为是不安全的(因为循环体可能永远不会被执行)。

初始化之前with 范围可以更安全,因为在with 语句之后我们可以安全地假设变量存在。另一方面,如果在with 语句中分配变量应该,在with 语句之前不初始化它实际上会导致额外的检查:如果以某种方式跳过分配,Python 将出错with 声明。

with 语句仅用于上下文管理目的。它强制(通过语法)您在 with 中打开的上下文在缩进结束时关闭。

【讨论】:

  • 那么我需要初始化吗?或者我可以像我正在做的那样在 with 语句之外使用变量 my_count 。有什么更好的做法?
  • @水晶:我用更多信息更新了答案。这是否回答了您的问题?
  • 感谢您的解释:D
  • 虽然感觉真的不像 Pythonic。我尽量避免使用稍后在 for 循环中初始化的变量,而我在 if 块中分配的变量在 else 块中总是有类似的分配。与 try/except 块类似。虽然 with 语句不需要这样的保护措施,但它只是看起来 / 错误 / 不知何故。 if 语句中的赋值也感觉有点糟糕,所以我更喜欢条件表达式。不幸的是 with-statements 似乎没有类似的东西..
  • @Willem Van Onsem,是的,我真的必须训练自己让我的 with-blocks 变短。通常发生的情况是,我 1) 编写一个带有 with 语句的函数(主要是打开一个文件),2) 自动将所有(间接)使用 'as' 变量的东西放入块中,包括任何返回语句,3)意识到 return 语句(通常)不应该在一个块中,4)再次取消缩进几乎所有内容(通常只有“读取”除外),5)感觉很糟糕,因为代码在我看来并不好看:-)。不过还好。
【解决方案2】:

您还应该查看 PEP-343 和 Python Documentation。很明显,它不是关于创建范围,而是关于使用Context Manager。我在上下文管理器上引用 python 文档

上下文管理器是一个对象,它定义了在执行 with 语句时要建立的运行时上下文。上下文管理器处理执行代码块所需的运行时上下文的进入和退出。上下文管理器通常使用 with 语句调用(在 with 语句一节中描述),但也可以通过直接调用它们的方法来使用。

上下文管理器的典型用途包括保存和恢复各种全局状态、锁定和解锁资源、关闭打开的文件等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多