What is the minimal subset of file methods I need to implement to get the full python file interface?
Python has the marvelous collections
module that has tools to allow you to implement a full dict
(for example) from a minimal set of methods. Is there a similar thing for the file
interface in Python? If not, what would you recommend as a minimal set of methods to implement for a file
-like object for duck-typing purposes?
And how do you deal with things that would like to use your file like object in a with
statement, like you can with a regular file, or who want to iterate over it (like yo开发者_C百科u can with a regular file) or who want to be able to call readline
or readlines
and have it do something intelligent and useful (like you can with a regular file)? Do you have to implement them all yourself? Or are there better options?
I know I can implement each and every single one of these myself, by hand. But the collections
interface allows me to implement a dict
by implementing just __len__
, __iter__
, __setitem__
, and __getitem__
. I get pop
, popitem
, clear
, update
, setdefault
, __contains__
, keys
, items
, values
, get
, __eq__
, and __ne__
all for free. There is a minimal interface for __dict__
defined, and if I implement it, I get the full dict
interface, all of the extra methods being implemented in terms of the minimal interface.
Similarly, I would like to know what the minimal interface for file is that I have to implement in order to get the full interface. Is there a way to get __enter__
, __exit__
, readline
, readlines
, __iter__
and next
if I just implement read
, write
and close
, or do I have to implement everything myself by hand each and every time I want the full file
interface?
The with statement requires a context manager:
http://docs.python.org/library/stdtypes.html#typecontextmanager
The file type is fully defined:
http://docs.python.org/library/stdtypes.html#file-objects
Seems pretty simple.
The documentation lists the methods and attributes of a file and a context manager. Implement those.
What more information do you need?
http://docs.python.org/library/contextlib.html?highlight=context%20manager
If you want all the methods to work, you have to implement all the methods. Unlike the collections, there is no abstract base class for files.
I would look at io.IOBase[1] and io.RawIOBase for >2.6 compatibility. This will keep you moving forward with 3.x (io implements the 3.x file interface).
[1] http://docs.python.org/library/io.html#i-o-base-classes
You kind of answered it yourself. While there is no set of "special" methods you need to implement the file interface, you can do it just by providing a couple of methods normally associated with files. Duck typing takes care of the rest.
You only really need a read
and/or a write
method (depending on whether you want it to be readable and/or writable) which behave the same as a normal file object. You can have a look at the Python file object reference to see all of the methods of a file object. Basically, the more you implement, the more situations your class will work in place of a file. (For example, if you implement seek
, then it will work in any function that performs seeking on a file.) Note that there is a continuum here, there is no absolute "it supports the file protocol or it doesn't." In fact, there is no way to work 100% in all the places that support file-like objects, because some code will access low-level details of the real file
type, and yours won't work there.
In summary, any class that implements read
and write
will work in most situations that require a "file-like object".
(Note that the special method names like __getitem__
for dicts are really not special, except they are used by special syntax like [key]
-- thats why dict has special method names and file does not.)
精彩评论