如何封装文件对象的只读读写操作?
我正在尝试对一个文件对象的读取和写入操作进行封装,特别是它的 readline()
和 write()
方法。
通常,我会简单地用一个包装函数来替代这些功能,像这样:
def log(stream):
def logwrite(write):
def inner(data):
print 'LOG: > '+data.replace('\r','<cr>').replace('\n','<lf>')
return write(data)
return inner
stream.write = logwrite(stream.write)
但是,文件对象的属性是只读的!我该如何正确地进行封装呢?
(注意:我实在懒得去封装整个文件对象……真的,我不想错过任何一个我没有正确封装的功能,或者未来版本的 Python 可能会新增的功能)
更多背景:
我正在尝试自动化与一个调制解调器的通信,这个调制解调器的 AT 命令集通过 telnet 会话在网络上可用。一旦登录,我就会“抓取”我想要通信的模块。在一段时间没有活动后,会发生超时,这会释放该模块(这样它就可以被网络上的其他用户使用……不过我不在乎,我是这个设备的唯一用户)。自动释放会在会话中写入一行特定的内容。
我想对从套接字构建的文件的 readline()
进行封装(参考 socket.makefile()
),这样当发生超时时,就会抛出一个特定的异常,这样我就可以在脚本中的任何地方检测到超时,并做出相应的反应,而不需要复杂化 AT 命令解析器……
(当然,我想这样做是因为超时的情况相当偶发,否则我只需不断给调制解调器发送命令,而没有任何副作用,仅仅是为了保持模块活跃)
(如果你有其他方法或策略来实现这个效果,欢迎提出)
1 个回答
3
使用 __getattr__
来包装你的文件对象。为你关心的方法提供修改过的版本。
class Wrapped(object):
def __init__(self, file_):
self._file = file_
def write(self, data):
print 'LOG: > '+data.replace('\r','<cr>').replace('\n','<lf>')
return self._file.write(data)
def __getattr__(self, attr):
return getattr(self._file, attr)
这样,对于那些你没有明确提供的属性请求,会转发到被包装的对象上的属性,你只需要实现你想要的部分就可以了。
logged = Wrapped(open(filename))