在“ with”语句内声明的变量是局部变量吗?

时间:2019-09-23 13:31:34

标签: python

我正在阅读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 个答案:

答案 0 :(得分:2)

,“带有”语句不会创建新的范围。

“ 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语句也不是单独的代码块。这只是优雅的尝试...最终阻止。它提取了一段“包含”的代码。

通过查看try ... except语句(在try内声明了变量)可以很容易地理解这一点:

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

我希望其他出于这个原因的人都清楚。

咨询网站:

https://www.geeksforgeeks.org/with-statement-in-python/

https://effbot.org/zone/python-with-statement.htm

答案 1 :(得分:2)

one 语句创建一个新范围:def语句。其他任何分配都将创建当前函数主体本地的名称。

例外是:

  • 声明为global的名称是指(模块)全局范围而不是局部函数体。
  • 声明为nonlocal的名称是指在最接近的函数范围(如果找不到其他名称,则为全局范围)中定义的名称。
  • Python解释器本身可以定义名称。

在您的示例中,f是局部变量或全局变量,具体取决于with语句出现的范围。 f绝对不是任何其他特定语句的本地变量。