gpt4 book ai didi

文件或无的 Python 上下文

转载 作者:太空狗 更新时间:2023-10-30 01:58:24 25 4
gpt4 key购买 nike

Python 将调用一个子进程,用户要么请求子进程 stdout 转到一个文件(或返回到 os.devnull),要么子进程输出将“实时”传递。

我目前最好的猜测是如何做到这一点似乎可行:

  • file_path 成为 open() 的有效输入
  • logging 为 bool 指示符,true 表示使用 file_path 进行日志记录,false 表示直通到 stdout。

with open(file_path, 'wb') if logging else None as shell_stdout:
subprocess.call(['ls'], stdout=shell_stdout)

在修补/测试中,这似乎是正确的值,我假设它与 subprocess.call 一起工作。但是,毫不奇怪,我得到以下异常:

AttributeError: __exit__

所以None不是上下文,它没有__exit__


目标

  • 如果用户不想记录,则根本不打开文件。
  • 使用上下文(由 stdlib 提供),(首选项;我无法想象手动执行文件打开/关闭操作会更干净。)
  • 不需要 try/catch(避免进一步嵌套的偏好)
  • 只调用一次subprocesses.call(非重复行)

那么,如何实现这种行为呢?或者你会建议做什么来代替/替代?

最佳答案

您可以创建一个“无操作”context manager :

import subprocess
import contextlib
@contextlib.contextmanager
def noop():
yield None

logging = False
file_path = '/tmp/out'

with open(file_path, 'wb') if logging else noop() as shell_stdout:
subprocess.call(['ls'], stdout=shell_stdout)

当 logging 为 True 时,条件表达式返回一个文件对象。当 logging 为 False 时,它​​返回一个 noop() 上下文管理器(因此它可以在 with-statement 中使用),它设置 shell_outNone 但在退出时不执行任何特殊操作。


Per the docs , 当 stdout=None,

... no redirection will occur; the child’s file handles will be inherited from the parent.

通常父级的标准输出等于 sys.stdout。但是,可以将 sys.stdout 重定向到其他地方,无论是显式(例如 sys.stdout = open('/tmp/stdout', 'wb'))还是间接地,例如通过使用重定向 sys.stdout 的模块。例如,标准库中的 fileinput 模块重定向 sys.stdout。在这种情况下,noop() 可能有助于将 stdout 定向到父级的 stdout,这可能与 sys.stdout 不同。

如果这个角落案例不影响你,那么Padraic Cunningham's solution更简单:

with open(file_path, 'wb') if logging else sys.stdout as shell_stdout:
subprocess.call(['ls'], stdout=shell_stdout)

关于文件或无的 Python 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28680442/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com