实现完整Python文件接口需要哪些最小文件方法子集?
Python有一个很棒的collections
模块,它提供了一些工具,让你可以用很少的方法来实现一个完整的dict
(字典)。那么,Python中有没有类似的东西可以用来处理file
(文件)接口呢?如果没有,你会推荐哪些最基本的方法来实现一个像文件一样的对象,以便进行鸭子类型(duck typing)?
而且,如何处理那些想要在with
语句中使用你的文件对象的情况,就像使用普通文件一样,或者想要遍历它(就像普通文件那样),或者想要调用readline
或readlines
并让它做一些聪明而有用的事情(就像普通文件那样)?你需要自己实现所有这些功能吗?还是有更好的选择?
我知道我可以手动实现每一个功能。但是,collections
接口让我只需要实现__len__
、__iter__
、__setitem__
和__getitem__
就可以实现一个dict
。这样我就可以免费获得pop
、popitem
、clear
、update
、setdefault
、__contains__
、keys
、items
、values
、get
、__eq__
和__ne__
等方法。只要我实现了__dict__
的最小接口,就能获得完整的dict
接口,所有额外的方法都是基于这个最小接口实现的。
同样,我也想知道,要实现完整的文件接口,我需要实现哪些最基本的接口。如果我只实现read
、write
和close
,是否就能获得__enter__
、__exit__
、readline
、readlines
、__iter__
和next
这些功能,还是说每次想要完整的file
接口时,我都得手动实现所有功能?
3 个回答
你其实已经部分回答了这个问题。虽然没有一套“特殊”的方法是必须要实现的来让一个类像文件一样工作,但你只需要提供一些通常和文件相关的方法就可以了。鸭子类型(Duck typing)会处理其他的事情。
你只需要一个 read
方法和/或一个 write
方法(这取决于你想让这个对象是可读的还是可写的),这些方法的行为要和普通的文件对象一样。你可以查看一下 Python 文件对象 的参考文档,看看文件对象有哪些方法。基本上,你实现的方法越多,你的类就能在更多需要文件的地方使用。(比如,如果你实现了 seek
方法,那么它就可以在任何需要对文件进行定位的函数中使用。)需要注意的是,这里是一个连续的过程,并没有绝对的“支持文件协议”或“不支持文件协议”。实际上,没有办法让你的类在所有支持类文件对象的地方都能100%工作,因为有些代码会访问真实 file
类型的低级细节,而你的类在这些地方就无法使用。
总之,任何实现了 read
和 write
方法的类在大多数需要“类文件对象”的情况下都能正常工作。
(注意,像 __getitem__
这样的特殊方法名对于字典来说并不是真的特殊,除了它们被像 [key]
这样的特殊语法使用——这就是为什么字典有特殊方法名而文件没有的原因。)
我建议你看看 io.IOBase[1] 和 io.RawIOBase,这样可以确保你的代码在 2.6 版本以上也能兼容。这样做可以帮助你顺利过渡到 3.x 版本,因为 io 模块实现了 3.x 的文件接口。
使用 with 语句需要一个上下文管理器:
http://docs.python.org/library/stdtypes.html#typecontextmanager
文件类型的定义很完整:
http://docs.python.org/library/stdtypes.html#file-objects
看起来挺简单的。
文档中列出了文件和上下文管理器的方法和属性。你需要实现这些。
你还需要什么更多的信息呢?
http://docs.python.org/library/contextlib.html?highlight=context%20manager
如果你想让所有的方法都能正常工作,你就得实现所有的方法。和集合不同,文件没有抽象基类。