nic*_*ole 55 python conditional indentation with-statement conditional-statements
有没有办法用with语句开始一段代码,但是有条件地?
就像是:
if needs_with():
with get_stuff() as gs:
# do nearly the same large block of stuff,
# involving gs or not, depending on needs_with()
Run Code Online (Sandbox Code Playgroud)
为了澄清,一种情况会在with语句中包含一个块,而另一种情况可能是同一个块,但不包含(即,好像它没有缩进)
最初的实验当然会给出压痕错误..
Mik*_*ike 53
Python 3.3 contextlib.ExitStack
就是针对这种情况而引入的.它为您提供了一个"堆栈",您可以根据需要向其添加上下文管理器.在你的情况下,你会这样做:
from contextlib import ExitStack
with ExitStack() as stack:
if needs_with():
gs = stack.enter_context(get_stuff())
# do nearly the same large block of stuff,
# involving gs or not, depending on needs_with()
Run Code Online (Sandbox Code Playgroud)
输入的任何内容都会像往常一样在语句末尾stack
自动exit
编辑with
.(如果没有输入任何内容,则这不是问题.)在此示例中,自动返回的内容get_stuff()
均为exit
ed.
如果你必须使用早期版本的python,你可能可以使用该contextlib2
模块,虽然这不是标准的.它将此功能和其他功能向后移植到早期版本的python.如果您喜欢这种方法,您甚至可以进行条件导入.
jam*_*lin 47
如果你想避免重复代码并使用3.7之前(contextlib.nullcontext
引入时)或3.3(引入时)的Python版本contextlib.ExitStack
,你可以做类似的事情:
class dummy_context_mgr():
def __enter__(self):
return None
def __exit__(self, exc_type, exc_value, traceback):
return False
Run Code Online (Sandbox Code Playgroud)
要么:
import contextlib
@contextlib.contextmanager
def dummy_context_mgr():
yield None
Run Code Online (Sandbox Code Playgroud)
然后将其用作:
with get_stuff() if needs_with() else dummy_context_mgr() as gs:
# do stuff involving gs or not
Run Code Online (Sandbox Code Playgroud)
你也可以get_stuff()
根据自己做出不同的回报needs_with()
.
(请参阅Mike的回答或Daniel的回答,了解您在以后的版本中可以做些什么.)
Dan*_*ous 14
从Python 3.7开始,您可以使用contextlib.nullcontext
:
from contextlib import nullcontext
if needs_with():
cm = get_stuff()
else:
cm = nullcontext()
with cm as gs:
# Do stuff
Run Code Online (Sandbox Code Playgroud)
contextlib.nullcontext
几乎只是一个无操作的上下文管理器.你可以传递一个它将产生的参数,如果你依赖于以下之后存在的东西as
:
>>> with nullcontext(5) as value:
... print(value)
...
5
Run Code Online (Sandbox Code Playgroud)
否则它只会返回None
:
>>> with nullcontext() as value:
... print(value)
...
None
Run Code Online (Sandbox Code Playgroud)
它非常整洁,请查看以下文档:https://docs.python.org/3/library/contextlib.html#contextlib.nullcontext
Ane*_*pic 10
实现此目的的第三方选项:https:
//pypi.python.org/pypi/conditional
from conditional import conditional
with conditional(needs_with(), get_stuff()):
# do stuff
Run Code Online (Sandbox Code Playgroud)
import contextlib
my_context = None # your context
my_condition = False # your condition
# Option 1 (Recommended)
with my_context if my_condition else contextlib.nullcontext():
print('hello 1')
# Option 2
with my_context if my_condition else contextlib.ExitStack():
print('hello 2')
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
10011 次 |
最近记录: |