如何在 Python 中对文件类型进行子类化?
我正在尝试对 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 操作已关闭的文件
。 我无法在 __init__()
中有意义地调用 file.__init__()
,因为我不想打开新文件,并且无法分配 < code>self.close = False 两者之一,因为它是只读属性。
我如何修改它,以便我可以执行 print 'foo'
操作,并使其支持所有标准 file
属性和方法?
I'm trying to subclass the built-in file
class in Python to add some extra features to stdin
and stdout
. Here's the code I have so far:
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')
The purpose is to add a timestamp to the beginning of each message, and to log everything to a log file. However, the problem I run into is that if I do this:
# log_file has already been opened
sys.stdout = TeeWithTimestamp(sys.stdout, log_file)
Then when I try to do print 'foo'
, I get a ValueError: I/O operation on closed file
. I can't meaningfully call file.__init__()
in my __init__()
, since I don't want to open a new file, and I can't assign self.closed = False
either, since it's a read-only attribute.
How can I modify this so that I can do print 'foo'
, and so that it supports all of the standard file
attributes and methods?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您也可以避免使用
super
:您将能够用它来编写。
You can as well avoid using
super
:You'll be able to write with it.
调用
file.__init__
是相当可行的(例如,在“/dev/null”上),但没有实际用途,因为您尝试覆盖write
并没有“采取”print
语句的目的 - 当后者看到sys.stdout
是的实际实例时,它会在内部调用真正的
(通过继承你就做到了这一点)。file.write
>file除了
write
之外,print
实际上并不需要任何其他方法,因此使您的类继承自object
而不是file
将工作。如果您需要其他文件方法(即
print
不是您所做的全部),最好建议您自己实现它们。Calling
file.__init__
is quite feasible (e.g., on '/dev/null') but no real use because your attempted override ofwrite
doesn't "take" for the purposes ofprint
statements -- the latter internally calls the realfile.write
when it sees thatsys.stdout
is an actual instance offile
(and by inheriting you've made it so).print
doesn't really need any other method exceptwrite
, so making your class inherit fromobject
instead offile
will work.If you need other file methods (i.e.,
print
is not all you're doing), you're best advised to implement them yourself.