我写了一个tee()
类,该类基于Triptych在https://stackoverflow.com/questions/616645/how-do-i-duplicate-sys-stdout-上的答案将stdout重定向到终端和文件 到 python中的日志文件。
它在我的程序运行的前几次有效,但在第3次运行时有效:
File "C:\Users\Dave\data\Code\Python\lib\nerdlib.py", line 351, in write
with open(self.name, "a", encoding="utf-8") as f:
TypeError: expected str, bytes or os.PathLike object, not NoneType
看来,即使在我执行了sys.stdout = self.old_stdout(将执行向量还原到它从其开始的位置)之后,仍然以某种方式调用了我的write方法(在这种情况下会出现错误)。
但是为什么我的方法仍然被调用?
在Spyder开发环境中会发生此错误-不确定是否相关。
代码在下面-很简单。
# based on Triptych's answer at https://stackoverflow.com/questions/616645/how-do-i-duplicate-sys-stdout-to-a-log-file-in-python
class tee():
''' Tees stdout to both a log file and the terminal.
if append is True (default), appends to existing file
if stderr is True (default), tees stederr to same file
Usage:
t = tee("filename.txt")
...
print(1, 2, 3)
...
t.__del__() # returns sys.stdout to original state
'''
def __init__(self, filepath, append=True, stderr=True):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.name = filepath
if (not append) or (not os.path.exists(self.name)):
makeEmptyFile(self.name)
sys.stdout = self
if stderr:
sys.stderr = self
def write(self, text):
self.old_stdout.write(text)
# open file, write, then close it again (slow, but safe - permits other processes to write to same file)
with open(self.name, "a", encoding="utf-8") as f:
f.write(text)
def flush(self):
pass
def stop(self):
sys.stdout = self.old_stdout
sys.stdout = self.old_stderr
self.name = None
def __del__(self):
self.stop()
问题来源:stackoverflow
这里的危险是,设置sys.stdout = sys.old_stdout
会阻止代码在本地替换上获得新的句柄,但不会阻止任何旧的 句柄正常工作。
作为一个人为的例子:
class MyThread(threading.Thread):
def __init__(self, log_dest=sys.stdout):
self.log_dest = log_dest
def run(self):
# ...do something-or-other, and occasionally...
self.log_dest.write('Hey, something happened')
由于初始化MyThread时会为log_dest分配一个值,因此将sys.stdout更改回其旧值不会阻止它继续尝试使用现在无效的对象。
回答来源:stackoverflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。