Python I/O:如何使用io模块中的wsgi.input流

1 投票
1 回答
1836 浏览
提问于 2025-04-17 07:27

在一个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()……

撰写回答