我正在尝试在Python中继承内置的file
类,为stdin
和stdout
添加一些额外的功能。这是我到目前为止的代码:
class TeeWithTimestamp(file):
"""
Class used to tee the output of a stream (such as stdout or stderr) into
another stream, and to add a timestamp to each message printed.
"""
def __init__(self, file1, file2):
"""Initializes the TeeWithTimestamp"""
self.file1 = file1
self.file2 = file2
self.at_start_of_line = True
def write(self, text):
"""Writes text to both files, prefixed with a timestamp"""
if len(text):
# Add timestamp if at the start of a line; also add [STDERR]
# for stderr
if self.at_start_of_line:
now = datetime.datetime.now()
prefix = now.strftime('[%H:%M:%S] ')
if self.file1 == sys.__stderr__:
prefix += '[STDERR] '
text = prefix + text
self.file1.write(text)
self.file2.write(text)
self.at_start_of_line = (text[-1] == '\n')
目的是在每条消息的开头添加一个时间戳,并将所有内容记录到日志文件中。但是,我遇到的问题是,如果我这样做:
# log_file has already been opened
sys.stdout = TeeWithTimestamp(sys.stdout, log_file)
然后当我尝试print 'foo'
时,我得到ValueError: I/O operation on closed file
。我无法在file.__init__()
中有意义地调用__init__()
,因为我不想打开新文件,也无法分配self.closed = False
,因为它是只读的属性。
如何修改此设置以便我可以执行print 'foo'
,以便它支持所有标准file
属性和方法?
答案 0 :(得分:12)
调用file.__init__
是非常可行的(例如,在'/ dev / null'上),但没有实际用途,因为为了{{1}的目的,你试图覆盖write
没有“接受” }}语句 - 当后者在print
看到file.write
是sys.stdout
的实际实例时(通过继承你已经这样做了),内部调用真实的file
。
print
之外, write
并不需要任何其他方法,因此让您的类继承自object
而不是file
。
如果您需要其他文件方法(例如print
并非您正在做的事情),建议您自己实施。
答案 1 :(得分:3)
您也可以避免使用super
:
class SuperFile(file):
def __init__(self, *args, **kwargs):
file.__init__(self, *args, **kwargs)
你可以用它来写。