python with语句 局部变量_关于python:’with’语句中有多个变量?

是否可以在Python中使用with语句声明多个变量?

就像是:

from __future__ import with_statement

with open("out.txt","wt"), open("in.txt") as file_out, file_in:

for line in file_in:

file_out.write(line)

......还是正在清理两个资源同时出现问题?

也许是这样的:将[expr1,expr2]作为f:然后使用f [0]和f [1]。

本来不错,因为不需要导入一些东西....但它不起作用AttributeError:'list'对象没有属性'exit'

如果python只有闭包,你就不需要with语句

你不需要使用with语句,对吗?您可以将file_out和file_in设置为None,然后执行try / except / finally打开它们并在try中处理它们,然后在最后关闭它们(如果它们不是None)。不需要双缩进。

其中许多答案都没有涉及超过两个语句的需要。从理论上讲,可能存在需要打开数十个上下文的应用程序,嵌套很快就会崩溃,因为任何行长度都会受到限制。

@Mark Amery。是的,但我先问:)

是否有可能将字段设置为与with open('./file') as arg.x = file:中的语句相同?

@ThorSummoner看到描述contextlib.ExitStack的答案。

从v3.1和Python 2.7开始,它可以在Python 3中实现。新的with语法支持多个上下文管理器:

with A() as a, B() as b, C() as c:

doSomething(a,b,c)

与contextlib.nested不同,这保证即使C()或__enter__()方法引发异常,a和b也会调用__exit__()。

是否可以在with open('./file') as arg.x = file:中将字段设置为与语句中的某些内容相同?

此外,有可能:A()为a,B(a)为b,C(a,b)为c:

class test2:x = 1; t2 = test2(),open('f2.txt')为t2.x:for t1.x.readlines()中的l1:print(l1); #Charlie Parker#在python 3.6中测试过

请注意,as是可选的。

contextlib.nested支持这个:

import contextlib

with contextlib.nested(open("out.txt","wt"), open("in.txt")) as (file_out, file_in):

...

更新:

引用文档,关于contextlib.nested:

Deprecated since version 2.7: The with-statement now supports this

functionality directly (without the confusing error prone quirks).

看拉法? Dowgird的回答是为了获取更多信息。

我很遗憾地说,但我认为nested上下文管理器是一个错误,永远不应该使用。在此示例中,如果打开第二个文件引发异常,则第一个文件根本不会关闭,从而完全破坏了使用上下文管理器的目的。

你为什么这么说?文档说使用嵌套等同于嵌套'with'

@Rafal:瞥一眼手册似乎表明python正确地嵌套了with语句。真正的问题是,如果第二个文件在关闭时抛出异常。

@Unknown:这也是我的阅读 - 据我所知,File对象在关闭时不会引发异常

@James:不,docs.python.org/library/contextlib.html#contextlib.nested文档中的等效代码与标准嵌套with块不同。在输入with块之前按顺序创建管理器:m1,m2,m3 = A(),B(),C()如果B()或C()失败但有异常,那么你唯一希望正确完成A( )是垃圾收集器。

@Rafal:在很多情况下,立即关闭所有非特殊出口都是合适的。例如,它是一种捕捉return和continue的简洁方法。

自2.7版以来已弃用。注意:with语句现在直接支持此功能(没有容易出错的容易出错的怪癖)。

请注意,如果将变量拆分为行,则必须使用反斜杠来换行换行符。

with A() as a, \

B() as b, \

C() as c:

doSomething(a,b,c)

括号不起作用,因为Python会创建一个元组。

with (A(),

B(),

C()):

doSomething(a,b,c)

由于元组缺少__enter__属性,因此会出现错误(无法识别并且不识别类类型):

AttributeError: __enter__

如果您尝试在括号内使用as,Python会在解析时捕获错误:

with (A() as a,

B() as b,

C() as c):

doSomething(a,b,c)

SyntaxError: invalid syntax

https://bugs.python.org/issue12782似乎与此问题有关。

我想你想这样做:

from __future__ import with_statement

with open("out.txt","wt") as file_out:

with open("in.txt") as file_in:

for line in file_in:

file_out.write(line)

这就是我目前的做法,但是嵌套的深度是我想要的两倍(意思是)它......

我认为这是最干净的方法 - 任何其他方法都难以阅读。亚历克斯马尔泰利的答案似乎更接近你想要的,但更不易读。为什么要嵌套这样一个问题呢?

诚然,这并不是什么大不了的事,但是,根据"导入这个"(又名"Python的禅"),"扁平比嵌套好" - 这就是我们将contextlib.nested添加到标准库的原因。顺便说一句,3.1可能有一个新的语法"用A()作为a,B()作为b:"(补丁是,到目前为止没有关于它的BDFL声明),以获得更直接的支持(显然,库解决方案不是'被认为是完美的......但是避免不必要的嵌套绝对是核心Python开发人员共同的目标。

@Alex:非常正确,但我们还必须考虑"可读性计数"。

@Andrew:我认为一个级别的缩进更好地表达了程序的预期逻辑,即"原子地"创建两个变量,并在以后一起清理它们(我意识到这实际上并不是发生了什么)。认为例外问题是一个交易破坏者

从Python 3.3开始,您可以使用contextlib模块中的类ExitStack。

它可以管理动态数量的上下文感知对象,这意味着如果您不知道要处理多少文件,它将特别有用。

文档中提到的规范用例是管理动态数量的文件。

with ExitStack() as stack:

files = [stack.enter_context(open(fname)) for fname in filenames]

# All opened files will automatically be closed at the end of

# the with statement, even if attempts to open files later

# in the list raise an exception

这是一个通用的例子:

from contextlib import ExitStack

class X:

num = 1

def __init__(self):

self.num = X.num

X.num += 1

def __repr__(self):

cls = type(self)

return '{cls.__name__}{self.num}'.format(cls=cls, self=self)

def __enter__(self):

print('enter {!r}'.format(self))

return self.num

def __exit__(self, exc_type, exc_value, traceback):

print('exit {!r}'.format(self))

return True

xs = [X() for _ in range(3)]

with ExitStack() as stack:

print(stack._exit_callbacks)

nums = [stack.enter_context(x) for x in xs]

print(stack._exit_callbacks)

print(stack._exit_callbacks)

print(nums)

输出:

deque([])

enter X1

enter X2

enter X3

deque([._exit_wrapper at 0x7f5c95f86158>, ._exit_wrapper at 0x7f5c95f861e0>, ._exit_wrapper at 0x7f5c95f86268>])

exit X3

exit X2

exit X1

deque([])

[1, 2, 3]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值