【问题标题】:how to wrap file object read and write operation (which are readonly)?如何包装文件对象的读写操作(只读)?
【发布时间】:2010-10-25 10:51:37
【问题描述】:

我正在尝试包装文件对象实例的读写操作(特别是 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 命令解析器复杂化的情况下做出适当的反应......

(当然,我想这样做是因为超时是非常虚假的,否则我会简单地向调制解调器提供命令而没有任何副作用,只是为了让模块保持活动状态)

(请随意提出任何其他方法或策略来达到此效果)

【问题讨论】:

  • 既然你只需要 readline() 和 write(),为什么还要担心“我没有包装的功能”呢?请说明将使用哪些神秘的其他功能。
  • 这个question 可以帮助你。您可以使用接受的答案来包装整个文件对象,但只实现您想要装饰的方法。您未显式装饰的方法将自动转发到内部对象。
  • 当你包装文件对象之类的东西时,你应该总是担心包装所有相关的 API 调用:通常假设可能会直接或间接调用任何方法,或者你正在设置以后自己会遇到一些晦涩难懂的错误。在这种情况下,这可能会转化为“某些 API 调用不会超时”。如果您不想为所有方法实现包装器,请使用引发 NotImplemented 的方法覆盖它们,以便立即注意到任何意外的方法调用。
  • 你为什么不只是子类文件?
  • @gnibbler:因为我不是创建文件对象的人。我使用socket.makefile() 从现有套接字获取文件对象。 (但我可能不知道如何对现有文件对象进行子类化...)

标签: python


【解决方案1】:

使用__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))

【讨论】:

  • 有趣的是,我只是尝试仅在定义 __init__()__getattr__() 方法的情况下使用它(作为初步测试),但它在试图将其变为listTypeError: 'Wrapped' object is not iterable。我可以通过添加一个只返回self._file__iter__() 方法来避免该错误,但我相信这会避开我最终定义的任何其他方法/处理。知道为什么必须显式定义 __iter__() 方法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-01
  • 2011-09-21
  • 2012-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多