我正致力于改进{3.}}的Python 3.X支持。它是文件系统的抽象。每个文件系统对象都有一个open方法,它返回一个类似文件的对象。
我面临的问题是open方法在Python 2.X上运行open
,但我希望它像io.open
一样工作,返回一些二进制或文本模式流。
我可以使用的方法是获取类似Python 2.X文件的对象,并返回一个适当的io流对象,该对象读取/写入底层文件类对象(但如果需要,则处理缓冲/ unicode等) )。
我在考虑以下内容:
def make_stream(file_object, mode, buffering, encoding):
# return a io instance
我看不出使用stdlib做任何直接的方法。但它让我觉得io模块必须在引擎盖下做,因为它是一个提供缓冲/ unicode功能的软件层。
答案 0 :(得分:1)
Python 2也包含相同的io
library。
使用from io import open
在Python版本中使用相同的工作。
然后,您的API应提供使用open()
类库提供相同功能的open()
等效项(称为make_stream()
或io
)。
您需要做的就是创建一个实现io.RawIOBase
ABC的类,然后使用库提供的其他类来根据需要添加缓冲和文本处理 < / EM>:
import io
class MyFileObjectWrapper(io.RawIOBase):
def __init__(self, *args):
# do what needs done
def close(self):
if not self.closed:
# close the underlying file
self.closed = True
# ... etc for what is needed (e.g. def read(self, maxbytes=None), etc.
def open(fileobj, mode='r', buffering=-1, encoding=None, errors=None, newline=None):
# Mode parsing and validation adapted from the io/_iomodule.c module
reading, writing, appending, updating = False
text, binary, universal = False
for c in mode:
if c == 'r':
reading = True;
continue
if c == 'w':
writing = True;
continue
if c == 'a':
appending = True;
continue
if c == '+':
updating = True;
continue
if c == 't':
text = True;
continue
if c == 'b':
binary = True;
continue
if c == 'U':
universal = reading = True;
continue
raise ValueError('invalid mode: {!r}'.format(mode))
rawmode = []
if reading: rawmode.append('r')
if writing: rawmode.append('w')
if appending: rawmode.append('a')
if updating: rawmode.append('+')
rawmode = ''.join(rawmode)
if universal and (writing or appending):
raise ValueError("can't use U and writing mode at once")
if text and binary) {
raise ValueError("can't have text and binary mode at once")
if reading + writing + appending > 1:
raise ValueError("must have exactly one of read/write/append mode")
if binary
if encoding is not None:
raise ValueError("binary mode doesn't take an encoding argument")
if errors is not None:
raise ValueError("binary mode doesn't take an errors argument")
if newline is not None:
raise ValueError("binary mode doesn't take a newline argument")
raw = MyFileObjectWrapper(fileobj)
if buffering == 1:
buffering = -1
line_buffering = True
else:
line_buffering = False
if buffering < 0:
buffering = SOME_SUITABLE_DEFAULT
if not buffering
if not binary:
raise ValueError("can't have unbuffered text I/O")
return raw
if updating:
buffered_class = io.BufferedRandom
elif writing or appending:
buffered_class = io.BufferedWriter
elif reading:
buffered_class = io.BufferedReader
buffer = buffered_class(raw, buffering)
if binary:
return buffer
return io.TextIOWrapper(buffer, encoding, errors, newline, line_buffering)
上面的代码主要是从Modules/_io/_iomodule.c
io_open
function改编而来,但原始文件对象被MyFileObjectWrapper
ABC的io.RawIOBase
子类替换。