【发布时间】:2021-07-13 21:24:22
【问题描述】:
我正在尝试将所有打印记录到日志文件中(并在实际消息之前添加时间戳,仅在日志文件中),但我无法弄清楚为什么 sys.stdout.write 被调用了两次。
import sys
from datetime import datetime
class Logger(object):
def __init__(self, filename="Default.log"):
self.stdout = sys.stdout
self.log = open(filename, "w")
def write(self, message):
self.stdout.write(message)
time_stamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
self.log.write(f"{time_stamp} - {message}")
self.log.flush()
def flush(self):
pass
sys.stdout = Logger("log_file.txt")
print("Hello world !")
终端输出:
Hello World !
log_file.txt 中的输出:
2021-04-19 18:43:14.800691 - Hello world !2021-04-19 18:43:14.800735 -
我在这里缺少什么?在调用self.log.flush()之后再次调用write方法,但是这里是message=''。
如果我忽略了 time_stamp 变量,它就像一个魅力,例如调用 self.log.write(message)。
我当然可以只检查消息是否为空,但我真的很想在这里了解我的问题!
我的解决方案
@iBug 给了我答案!我不知道 print 确实以这种方式工作:一次写入数据调用,一次写入调用end 关键字,默认为\n。
我的解决方案是添加一个变量 self._hidden_end 到 mthe Logger 类,该类初始化为 0,然后每次调用 write 时切换以检查它我应该在写入日志之前添加一个时间戳。
import sys
from datetime import datetime
class Logger(object):
def __init__(self, filename="Default.log"):
self.stdout = sys.stdout
self.log = open(filename, "w")
self._hidden_end = 0
def write(self, message):
self.stdout.write(message)
if not self._hidden_end:
time_stamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
message = f"{time_stamp} - {message}"
self._hidden_end ^= 1
self.log.write(message)
self.log.flush()
def flush(self):
pass
sys.stdout = Logger("log_file.txt")
print("Hello world !")
欢迎对我上面的解决方案提出任何想法! :)
【问题讨论】:
-
恐怕这就是
print()的工作方式——一次用于数据,一次用于换行(即隐藏的print(end='\n')) -
非常感谢 - 这解释了我的问题 :)
-
@amkleist 您应该从问题中删除您的解决方案并将其作为答案发布。此外,“对我的解决方案的任何想法”都过于宽泛。 Stack Overflow 是针对关于您的代码的特定问题。对于一般的代码审查,codereview.stackexchange.com 可能是一个更好的地方,但记得先检查他们的on-topic 指南
-
@iBug 请添加答案而不是评论。请参阅Comment everywhere 上的我什么时候不应该发表评论?部分。
-
@SᴀᴍOnᴇᴌᴀ 这只是一个(希望是正确的)推测,我没有检查代码或搜索任何参考资料。这是 IMO 留下潜在但不完整的“答案”作为评论的一个很好的理由。
标签: python python-3.x file stdout write