requests 不能发送 bytearray 数据

requests 不能发送 bytearray 数据

import requests
body = b"abc"
body = bytearray(body)
r = requests.post('https://example.com', data=body)
# r = requests.post('https://example.com', data=memoryview(body))
print(r.status_code)
TypeError                                 Traceback (most recent call last)
~/.pyenv/versions/3.7.0/Python.framework/Versions/3.7/lib/python3.7/http/client.py in send(self, data)
    976         try:
--> 977             self.sock.sendall(data)
    978         except TypeError:

~/.pyenv/versions/3.7.0/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/contrib/pyopenssl.py in sendall(self, data)
    330         while total_sent < len(data):
--> 331             sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE])
    332             total_sent += sent

~/.pyenv/versions/3.7.0/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/contrib/pyopenssl.py in _send_until_done(self, data)
    319             try:
--> 320                 return self.connection.send(data)
    321             except OpenSSL.SSL.WantWriteError:

~/.pyenv/versions/3.7.0/Python.framework/Versions/3.7/lib/python3.7/site-packages/OpenSSL/SSL.py in send(self, buf, flags)
   1731         if not isinstance(buf, bytes):
-> 1732             raise TypeError("data must be a memoryview, buffer or byte string")
   1733         if len(buf) > 2147483647:

TypeError: data must be a memoryview, buffer or byte string

很正常的请求,但是请求的内容不能是 bytearray ,有的电脑可以提交 bytearray 类型数据,

网上的帖子都说是 pyopenssl 的问题,虽然到最后也不知道是什么问题。

异常说提交的内容必须是 memoryview, buffer or byte string,将提交的内容更改为 ``memoryview`。

memoryview

可变的字节序列,python3str 默认是 unicode 编码,只能通过 bytearray 才能按字节访问。

strbytearray 的切片操作会产生新的切片 strbytearray 并拷贝数据,使用 memoryview 之后不会。

In [72]: stra = bytearray(b'abcde')

In [73]: strb = stra[:3]

In [74]: stra
Out[74]: bytearray(b'abcde')

In [75]: strb
Out[75]: bytearray(b'abc')
In [91]: a = bytearray(b'aaaa')	# 创建字节数组

In [92]: b = memoryview(a)	# 创建内存视图

In [93]: b.readonly	# 可写的内存视图
Out[93]: False

In [94]: c = b[:2]	# 不会产生新的 bytearray

In [95]: c
Out[95]: <memory at 0x125fca048>

In [97]: c[:2] = b'ww'	# 直接对b数据的修改

In [98]: c.tobytes()
Out[98]: b'ww'

In [99]: b.tobytes()
Out[99]: b'wwaa'
 
In [100]: a = b'aaaa'	

In [101]: b = memoryview(a)	

In [102]: b.readonly	# 只能读
Out[102]: True

使用 memoryview 可避免大的 str 进行分段解析时的大量切片操作。

你可能感兴趣的:(Python模块,Requests)