为了账号安全,请及时绑定邮箱和手机立即绑定

在“with”语句中声明的变量是本地的吗?

在“with”语句中声明的变量是本地的吗?

慕田峪9158850 2022-06-02 16:41:08
我正在阅读 StackOverflow 中的一个问题,其中用户连续两次应用“with”语句,将结果从第一个 with 语句中声明的变量流水线化到第二个。像这样(简单的例子):with open('first_file.txt', 'r') as f:   loaded_file = f.readlines()   #...Prepare a csv file somehow - loaded_file is not declared outside with...with open("second_file.csv", "w") as f:   for line in loaded_file:      f.write(line+"\n")考虑到变量作用域,为什么它会起作用?
查看完整描述

2 回答

?
慕运维8079593

TA贡献1876条经验 获得超5个赞

不,“with”语句不会创建新范围。


“With”语句是 Python 开发团队开发的一种资源,用于概括一种常见的(强烈推荐的)实践,即即使在发生异常后也关闭打开的资源。想象以下情况:


try:

   f = open('file.txt', 'w')

   #Do some processing that can raise exceptions and leave 'f' open, eventually locking the file or having trash data loaded into RAM.

   #To avoid this situation, a mindful developer will do the following:

finally:

   f.close()

它很容易变得冗长。


为了解决这个问题,python 开发团队建议使用一些封装这个过程的dunder方法: __enter__() 和 __exit__() - 当你使用“with”语句时,它们会在“幕后”被调用。


您甚至可以在自己的类中实现它们!


class controlled_execution:

    def __enter__(self):

        set things up

        return thing

    def __exit__(self, type, value, traceback):

        tear things down

with controlled_execution() as thing:

    some code

最后,即使有标识,with 语句也不是单独的代码块。这只是一个优雅的尝试...finaly 块。它抽象了一段“包含”的代码。


这可以通过查看带有在 try 中声明的变量的 try...except 语句来轻松理解:


x = 10

try:

    y = load_using_failable_function()

    z = 5

except FunctionFailureException:

    y = 10

#If you treat it properly, there's nothing wrong with doing:

x = x + y + z


我希望其他寻找这个原因的人都清楚。


查看完整回答
反对 回复 2022-06-02
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

只有一个语句创建了一个新范围:def语句。任何其他赋值都会创建一个当前函数体本地的名称。

例外情况是:

  • 声明的名称global是指(模块)全局范围而不是本地函数体。

  • 声明nonlocal的名称是指在最近的包含函数范围(如果没有找到其他名称,则为全局范围)中定义的名称

  • Python 解释器本身可以定义名称。

在您的示例中,f是局部变量还是全局变量,具体取决于with语句发生的范围。绝不是f任何其他特定声明的本地化。


查看完整回答
反对 回复 2022-06-02
  • 2 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信