Python I/O:如何使用io模块中的wsgi.input流
在一个WSGI应用中,我们可以从 wsgi.input 字段读取输入的数据:
def application(env, start_response):
.....
data = env['wsgi.input'].read(num_bytes)
.....
不过,我想用新的 io 模块来包装这个像文件一样的对象:
import io
def application(env, start_response):
.....
f = io.open(env['wsgi.input'], 'rb')
buffer = bytearray(buff_size)
read = f.readinto(buffer)
.....
问题是 io.open
不接受这种类型的文件对象。有没有什么办法可以做到这一点?我需要从 env['wsgi.input']
读取数据到一个缓冲区。
1 个回答
2
io.open()
函数的第一个参数不能是文件对象。
不过,它可以接受一个整数,这个整数代表一个打开文件的句柄。所以你可以尝试使用:
f = io.open(env['wsgi.input'].fileno, 'rb')
补充说明:
io模块是为Python 3写的,在字符串处理上和Python 2有很大不同。在Python 3中,调用以二进制模式打开的文件的 read()
方法会返回一个 bytes
对象,而在Python 2中则返回一个 str
。但是,当使用 io
模块并以二进制模式包装文件时,io模块期望 read()
返回 bytes
。
你可以尝试修复你原来的文件对象,让它返回 bytes
:
def fix(file):
# wrap 'func' to convert its return value to bytes using the specified encoding
def wrap(func, encoding):
def read(*args, **kwargs):
return bytes(func(*args, **kwargs), encoding)
return read
file.read = wrap(file.read, 'ascii')
fix(env['wsgi.input'])
f = io.open(env['wsgi.input'].fileno, 'rb')
上面的函数包装了 read()
方法,但可以进一步扩展来包装 readline()
。另外,还需要做一些小的额外工作来包装 readlines()
……