使用SFTP上传JSON内容时遇类型错误与属性错误的问题
问题解决:SFTP上传JSON数据时的两个错误处理
原始需求
要上传的目标数据结构:
sample = {'Details': [{'user1': '{"d8": "X121", "d0": "NIL", "d4": false, "d3": false, "d2": false}', 'name': 'set a sample'}], 'person1': 1}
第一次尝试的代码及错误
代码
s1 = json.dumps(sample).replace('"', '"').replace("'", "'") ftp = ssh.open_sftp() ftp.putfo(BytesIO(s1), 'newfile.txt')
错误信息
Reason: <class 'TypeError'> a bytes-like object is required, not 'str'
第二次修改后的代码及错误
代码
import json per_json = {'d8': 'X121', 'd0': 'NIL', 'd4': False, 'd3': False, 'd2': False} p1 = { "name" : "set a sample" } p1["additional_info"] = json.dumps(per_json) p1_list={"person1":1} p1_list["Details"]=[p1] s1 = json.dumps(p1_list).replace('}"', "}").replace('"{', "{").replace('\\"', '"') ftp = ssh.open_sftp() ftp.putfo(s1, 'newfile.txt') ftp.close()
错误信息
Reason: <class 'AttributeError'> 'str' object has no attribute 'read'
错误原因及解决方法
第一个错误:TypeError: a bytes-like object is required, not 'str'
原因:BytesIO 要求传入字节类型数据,但你传入的是字符串。json.dumps() 返回的是字符串,直接传给 BytesIO 会触发类型错误。
解决:把字符串通过 str.encode('utf-8') 转成字节,再传入 BytesIO。
第二个错误:AttributeError: 'str' object has no attribute 'read'
原因:ftp.putfo() 的第一个参数必须是类文件对象(拥有read()方法的对象),直接传字符串不符合要求,因为字符串没有read()方法。
解决:将字符串包装成BytesIO或StringIO实例,再传给putfo()。
最终正确代码
针对原始需求的正确上传代码,无需多余的字符串替换操作(json.dumps()会自动处理格式,手动替换反而容易破坏JSON结构):
import json from io import BytesIO # 原始目标数据 sample = { 'Details': [ { 'user1': '{"d8": "X121", "d0": "NIL", "d4": false, "d3": false, "d2": false}', 'name': 'set a sample' } ], 'person1': 1 } # 序列化JSON并转成字节流类文件对象 json_str = json.dumps(sample) file_like_obj = BytesIO(json_str.encode('utf-8')) # SFTP上传 ftp = ssh.open_sftp() ftp.putfo(file_like_obj, 'newfile.txt') ftp.close()
如果使用你修改后的p1_list结构,代码逻辑一致:
import json from io import BytesIO per_json = {'d8': 'X121', 'd0': 'NIL', 'd4': False, 'd3': False, 'd2': False} p1 = {"name": "set a sample"} p1["additional_info"] = json.dumps(per_json) p1_list = {"person1": 1, "Details": [p1]} # 序列化+转字节+包装成类文件对象 json_str = json.dumps(p1_list) file_like_obj = BytesIO(json_str.encode('utf-8')) ftp = ssh.open_sftp() ftp.putfo(file_like_obj, 'newfile.txt') ftp.close()
关键注意点
BytesIO必须接收字节类型数据,字符串需通过encode()转换。putfo()仅接受类文件对象,不能直接传字符串。- 避免无意义的字符串替换:
json.dumps()会自动处理引号转义,手动修改会破坏JSON格式。
内容的提问来源于stack exchange,提问作者aΨVaN
相关产品推荐
相关产品推荐

