Python2.7迁移3.7调用poster3.multipart_encode上传文件报TypeError
问题根因
你遇到的异常是因为 poster3 库在 Python 3 环境下的 multipart_encode 方法返回的数据流生成器 datagen 中混合了 str 和 bytes 两种类型的数据:
- 请求头部分为合法
bytes类型,因此第一块数据发送正常 - 后续 multipart 边界、字段描述等内容为
str类型,发送时无法被ssl.sendall方法识别,触发TypeError
修复方案
方案一:最小改动适配现有代码
仅需要在获取 datagen 后额外加一层类型转换,把所有 str 类型的块编码为 bytes 即可:
datagen, headers = poster3.encode.multipart_encode( [('data', simplejson.dumps(data).encode('UTF-8')), # 这里把原代码的json.dumps改成simplejson.dumps和导入对齐 ('filename', (path + filename).encode('UTF-8')), ('file', open(path + filename, 'rb'))]) # 新增以下行转换所有块为bytes类型 datagen = (chunk.encode('utf-8') if isinstance(chunk, str) else chunk for chunk in datagen)
方案二:使用requests库简化文件上传逻辑(推荐)
poster3 属于维护状态较差的旧库,直接使用 requests 库实现 multipart 上传可以避免很多 Python 2/3 兼容问题:
- 先安装依赖:
pip install requests - 替换原有上传逻辑代码:
import requests import base64 import simplejson # 构造鉴权头 auth_str = ('%s:%s' % (self.username, self.password)).replace('\n', '').encode() base64string = base64.standard_b64encode(auth_str).decode() headers = { "Authorization": "Basic %s" % base64string } # 构造上传参数 path = '/usr/local/audit_data/' filename = 'SN121838027160.png' incidentNoteId = '14122370' data = { 'incidentNotes': simplejson.dumps({'id': incidentNoteId}), 'name': filename, } files = { 'file': open(path + filename, 'rb') } # 发送请求 response = requests.post( self.PATH_ATTACHMENTS, data=data, files=files, headers=headers ) print(response.json())
内容的提问来源于stack exchange,提问作者user2117830
相关产品推荐
相关产品推荐

