我正在尝试使用以下代码来处理终端和IDLE shell。它旨在将标准输出分割为屏幕和日志文件。
class Tee(object):
def __init__(self, name, mode):
self.filename = open(name, mode)
self.stdout = sys.stdout
sys.stdout = self
def __del__(self):
sys.stdout = self.stdout
self.filename.close()
def write(self, data):
self.stdout.write(data)
self.filename.write(data)
Tee('logfile.log', 'wb')
print 'test123'
如果我从终端运行此代码,它可以正常工作。如果我从IDLE执行它,它会按原样打印,但日志文件中没有文本,也不会抛出任何异常。为什么这可以从命令promt而不是IDLE工作?我该怎么做才能使它在两种环境中都能正常工作?我在Win7和Python 2.7上。
编辑: 我把它放在一起用于陈述。这是我第一次上课,所以欢迎提出改进建议。
newlog = True
class Tee(object):
def __init__(self, name, mode=''):
global newlog
if newlog:
self.filename = open(name, 'w'+mode)
else:
self.filename = open(name, 'a'+mode)
newlog = False
def __enter__(self):
self.stdout = sys.stdout
sys.stdout = self
return self
def __exit__(self, name, mode, data):
sys.stdout = self.stdout
self.filename.close()
def __del__(self):
try:
self.filename.close()
sys.stdout = self.stdout
except:
pass
def startlog(self):
self.stdout = sys.stdout
sys.stdout = self
def stoplog(self):
self.filename.close()
sys.stdout = self.stdout
def write(self, data):
self.stdout.write(data)
self.filename.write(data)
self.filename.flush()
with Tee('logfile.log', 'b'):
print 'I am the walrus'
print 'coocoocachoo'
Tee = Tee('logfile.log')
Tee.startlog()
print 'I am the eggman'
Tee.stoplog()
print 'coocoocachoo'
答案 0 :(得分:2)
logfile.log不为空,它只是没有被刷新。 尝试:
sys.stdout.filename.flush()
你能做的就是写一个更全面的包装。想法 - 你甚至可以用更通用的方式做到这一点,喜欢这样的东西(这里可能会有一些问题需要解决):
import functools
class Tee(object):
def __init__(self, name, mode)
.
.
for name in ('write', 'flush', ...):
setattr(self, name, functools.partial(self._wrapper, name))
def _wrapper(func_name, *args, **kw):
getattr(self.filename, name)(*args, **kw)
getattr(self.stdout, name)(*args, **kw)