我正在阅读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")
考虑变量作用域,为什么起作用?
答案 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
我希望其他出于这个原因的人都清楚。
咨询网站:
答案 1 :(得分:2)
仅 one 语句创建一个新范围:def
语句。其他任何分配都将创建当前函数主体本地的名称。
例外是:
global
的名称是指(模块)全局范围而不是局部函数体。nonlocal
的名称是指在最接近的函数范围(如果找不到其他名称,则为全局范围)中定义的名称。在您的示例中,f
是局部变量或全局变量,具体取决于with
语句出现的范围。 f
绝对不是任何其他特定语句的本地变量。