我已将logger
配置为在终端stdout
和文件上打印,因此我可以拥有可以参考的日志消息存档。
通过向FileHandler
对象添加logging
可以轻松完成此操作。容易腻。
我现在想要完成的是当遇到解析错误时,使argparse
同时记录到同一个文件以及日志到stdout。到目前为止它只打印到stdout
。我查看了argparse
documentation,但我无法找到有关为argparse
设置不同输出流或管道的任何信息。
有可能吗?怎么样?
答案 0 :(得分:6)
查看argparse.py source code似乎没有办法配置此行为。
我的建议是:
覆盖/补丁:
print_*
方法error
方法。 print_*
方法似乎采用可选的file
参数,默认为_sys.stdout
。
更新:或者您可以执行以下操作:在解析参数时临时重定向sys.stdout
:
from contextlib import contextmanager
@contextmanager
def redirect_stdout_stderr(stream):
old_stdout = sys.stdout
old_stderr = sys.stderr
sys.stdout = stream
sys.stderr = stream
try:
yield
finally:
sys.stdout = old_stdout
sys.stderr = old_stderr
with redirct_stdout_stderr(logstream):
args = parser.parse_args()
答案 1 :(得分:4)
似乎无法通过API执行此操作。
但是,您可以执行以下操作:
class LoggingArgumentParser(argparse.ArgumentParser):
"""Custom ArgumentPaarser that overrides _print_message"""
def _print_message(self, message, file=None):
if message:
logger.write(message)
答案 2 :(得分:1)
虽然@James Mills给出的答案很好并且可以解决问题,但是在这种情况下不需要生成器。因此,收益是多余的。实现该目标的另一种方法(无需生成器)是编写自己的 context manager ,而无需使用内置的 contextlib.contextmanager 装饰器。如下所示。
class redirect_stdout_stderr(object):
def __init__(self, stream):
# Save the old std streams
self.old_stream = sys.stdout
self.old_error_stream = sys.stderr
self.fstream = stream
def __enter__(self):
# Change the std streams to your streams when entering
sys.stdout = self.fstream
sys.stderr = self.fstream
def __exit__(self, exc_type, exc_value, exc_traceback):
# Change the std streams back to the original streams while exiting
sys.stdout = self.old_stream
sys.stderr = self.old_error_stream
根据您的情况,您可以执行以下操作。
with redirect_stdout_stderr(logstream):
# __enter__() is executed
args = parser.parse_args()
# __exit__() is executed
希望这会有所帮助!