简体   繁体   English

python 中是否可以有一个可选的 with/as 语句?

[英]Is it possible to have an optional with/as statement in python?

Instead of this:取而代之的是:

FILE = open(f)
do_something(FILE)
FILE.close()

it's better to use this:最好使用这个:

with open(f) as FILE:
    do_something(FILE)

What if I have something like this?如果我有这样的事情怎么办?

if f is not None:
   FILE = open(f)
else:
   FILE = None
do_something(FILE)
if FILE is not None:
    FILE.close()

Where do_something also has an "if FILE is None" clause, and still does something useful in that case - I don't want to just skip do_something if FILE is None.哪里还do_something有一个“如果文件是无”的条款,而且还做一些有用的事情在这种情况下-我希望只是跳过do_something如果FILE是无。

Is there a sensible way of converting this to with/as form?有没有一种明智的方式将其转换为 with/as 形式? Or am I just trying to solve the optional file problem in a wrong way?还是我只是想以错误的方式解决可选文件问题?

If you were to just write it like this:如果你只是这样写:

if f is not None:
    with open(f) as FILE:
        do_something(FILE)
else:
    do_something(f)

( file is a builtin btw ) file是内置的顺便说一句)

Update更新

Here is a funky way to do an on-the-fly context with an optional None that won't crash:这是一种使用不会崩溃的可选 None 进行动态上下文的时髦方法:

from contextlib import contextmanager

none_context = contextmanager(lambda: iter([None]))()
# <contextlib.GeneratorContextManager at 0x1021a0110>

with (open(f) if f is not None else none_context) as FILE:
    do_something(FILE)

It creates a context that returns a None value.它创建了一个返回 None 值的上下文。 The with will either produce FILE as a file object, or a None type. with要么产生 FILE 作为文件对象,要么产生 None 类型。 But the None type will have a proper __exit__但是 None 类型会有一个适当的__exit__

Update更新

If you are using Python 3.7 or higher, then you can declare the null context manager for stand-in purposes in a much simpler way:如果您使用的是 Python 3.7或更高版本,那么您可以以更简单的方式声明空上下文管理器用于替代目的:

import contextlib
none_context = contextlib.nullcontext()

You can read more about these here:您可以在此处阅读有关这些的更多信息:

https://docs.python.org/3.7/library/contextlib.html#contextlib.nullcontext https://docs.python.org/3.7/library/contextlib.html#contextlib.nullcontext

Since Python 3.7, you can also do从 Python 3.7 开始,你也可以这样做

from contextlib import nullcontext

with (open(file) if file else nullcontext()) as FILE:
    # Do something with `FILE`
    pass

See the official documentation for more details.有关更多详细信息,请参阅官方文档

This seems to solve all of your concerns.这似乎解决了您的所有疑虑。

if file_name is not None:
    with open(file_name) as fh:
        do_something(fh)
else:
        do_something(None)

something like:就像是:

if file:      #it checks for None,false values no need of "if file is None"
    with open(file) as FILE:
        do_something(FILE)
else:
    FILE=None

In Python 3.3 and above, you can use contextlib.ExitStack to handle this scenario nicely在 Python 3.3 及更高版本中,您可以使用contextlib.ExitStack很好地处理这种情况

with contextlib.ExitStack() as stack:
    FILE = stack.enter_context(open(f)) if f else None
    do_something(FILE)

Python 3.7 supports contextlib.nullcontext , which can be used to avoid creating your own dummy context manager. Python 3.7 支持contextlib.nullcontext ,可用于避免创建自己的虚拟上下文管理器。

This examples shows how you can conditionally open a file or use the stdout :此示例显示了如何有条件地打开文件或使用stdout

import contextlib
import sys

def write_to_file_or_stdout(filepath=None, data):
    with (
            open(filepath, 'w') if filepath is not None else
            contextlib.nullcontext(sys.stdout)
    ) as file_handle:
        file_handle.write(data)

contextlib.nullcontext() can be called without any arguments if the value can be None.如果值可以是 None,则可以在没有任何参数的情况下调用contextlib.nullcontext()

While all of the other answers are excellent, and preferable, note that the with expression may be any expression, so you can do:虽然所有其他答案都很好,而且更可取,但请注意with表达式可以是任何表达式,因此您可以执行以下操作:

with (open(file) if file is not None else None) as FILE:
    pass

Note that if the else clause were evaluated, to yield None this would result in an exception, because NoneType does not support the appropriate operations to be used as a context manager.请注意,如果对else子句求值,则生成None这将导致异常,因为NoneType不支持用作上下文管理器的适当操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python XPath:是否可以有可选的XPath查询? - Python XPath : Is it possible to have optional XPath query? Python-带可选对象的语句 - Python - with statement with optional object 是否可以在 python 2.7 中的打印语句旁边有 a.join function 和 %(var)? - Is it possible to have a .join function and a % (var) next to a print statement in python 2.7? 在 Snakemake 中是否可以有“可选”通配符或文件名的一部分? - Is it possible in Snakemake to have “optional” wildcard or part of the filename? Snakemake中是否可以有一个可选的输出文件? - Is it possible to have an optional output file in Snakemake? 是否可以使用带有排列的if / else语句 - is it possible to have an if/else statement with permutations 是否可以将其包装在Python的“ with”语句中? - Is it possible to wrap this in a Python “with” statement? 为什么不能在Python的TRY块中使用IF语句,如果可能的话,这是不错的做法? - Why is it not possible to have an IF statement in a TRY block in Python, and if somehow possible, is it good practice? Python函数可选参数 - 可以添加为条件? - Python function optional arguments - possible to add as condition? 是否可以通过导入向python3添加语句? 或者我是否必须修改c文件并重新编译 - Is it possible to add a statement to python3 via an import? Or do I have to modify c files and recompile
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM