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

在python中是否可以有一个可选的with/as语句?,python,file-io,with-statement,Python,File Io,With Statement,与此相反: FILE = open(f) do_something(FILE) FILE.close() 最好使用这个: with open(f) as FILE: do_something(FILE) 如果我有这样的东西呢 if f is not None: FILE = open(f) else: FILE = None do_something(FILE) if FILE is not None: FILE.close() Where do_somethi

与此相反:

FILE = open(f)
do_something(FILE)
FILE.close()
最好使用这个:

with open(f) as FILE:
    do_something(FILE)
如果我有这样的东西呢

if f is not None:
   FILE = open(f)
else:
   FILE = None
do_something(FILE)
if FILE is not None:
    FILE.close()
Where do_something还有一个“if FILE is None”子句,在这种情况下仍然会执行一些有用的操作-我不想跳过do_something if FILE is None


是否有一种合理的方式将其转换为with/as形式?或者我只是试图以错误的方式解决可选文件问题?

如果您只是这样编写:

if f is not None:
    with open(f) as FILE:
        do_something(FILE)
else:
    do_something(f)
文件
是内置的btw)

更新

下面是一种通过可选的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)
您可以在此处阅读有关这些的更多信息:


这似乎解决了您所有的问题

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

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

尽管所有其他答案都很好,而且更可取,但请注意,
with
表达式可以是任何表达式,因此您可以执行以下操作:

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

请注意,如果对
else
子句进行求值,以产生
None
这将导致异常,因为
NoneType
不支持用作上下文管理器的适当操作

自Python 3.7以来,您还可以

从contextlib导入nullcontext
将(打开(文件)if file else nullcontext()作为文件:
#用文件做些什么`
通过

更多细节,请参见。

@sberry-我看到我们几乎拥有相同的东西,彼此非常接近:-)我希望避免重复
做一些事情,因为在实际情况中它是一个更大的代码块(尽管我可以将它粘贴在函数中,等等)。但这可能是我能做的最好的了。我刚刚添加了一个有趣的小例子,说明如何做你想做的事。请注意,
none\u context
只能使用一次。我更喜欢将其设置为可调用的:
def none\u上下文(a=none):返回contextmanager(iter)([a])
此外,如果引发异常,它将失败(
AttributeError:'listiterator'对象没有属性“throw”
)。这更可靠:
def none\u context(a=none):返回contextmanager(lambda:[a]中x代表x)(
对不起,我没有说清楚。希望问题的编辑版本更有意义。事实上,我想做一些事情来运行,即使文件是无-它有其他有用的功能,它的文件相关部分是可选的。哦,真棒!我没有意识到这一点。看起来这正是我需要的。等等……你确定这样行吗?没有一个类型会崩溃,因为它没有
属性错误:\uuuu exit\uuuu
@jdi-该死,你说得对,它确实崩溃了。。。回到绘图板:(@jdi:Fair point。不过,我想在此强调语法和可能性。我将进行编辑,以明确这将在执行时失败。@Marcin:我最终得到了一个动态的非类型上下文,在我的回答中,它与您打算的工作方式相同。我希望避免重复
do\u something
,因为它是一个更大的c真实情况下的大量代码(尽管我可以将其粘贴到函数中,等等),但这可能是我能做的最好的了。
with (open(file) if file is not None else None) as FILE:
    pass