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
可变的字节序列,python3 中 str 默认是 unicode 编码,只能通过 bytearray 才能按字节访问。
str 和 bytearray 的切片操作会产生新的切片 str 和 bytearray 并拷贝数据,使用 memoryview 之后不会。
In [72]: stra = bytearray(babcde) In [73]: strb = stra[:3] In [74]: stra Out[74]: bytearray(babcde) In [75]: strb Out[75]: bytearray(babc)
In [91]: a = bytearray(baaaa) # 创建字节数组 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] = bww # 直接对b数据的修改 In [98]: c.tobytes() Out[98]: bww In [99]: b.tobytes() Out[99]: bwwaa In [100]: a = baaaa In [101]: b = memoryview(a) In [102]: b.readonly # 只能读 Out[102]: True
使用 memoryview 可避免大的 str 进行分段解析时的大量切片操作。
