为何Flask会将JSON响应中的整数键转换为字符串?
为何Flask会将JSON响应中的整数键转换为字符串?
问题现象
当Flask接口返回带有整数键的字典时,客户端接收到的JSON响应中,整数键会被自动转换为字符串键,导致测试断言失败。
复现代码
app.py
from flask import Flask app = Flask(__name__) @app.route('/test', methods=['GET']) def test_endpoint(): return {1: "test"}, 200 if __name__ == '__main__': app.run(debug=True)
test_app.py
import pytest from app import app @pytest.fixture def client(): app.config['TESTING'] = True with app.test_client() as client: yield client def test_test_endpoint(client): response = client.get('/test') assert response.status_code == 200 assert response.json == {1: "test"}
测试失败信息
====================================================== FAILURES ====================================================== _________________________________________________ test_test_endpoint _________________________________________________ client = <FlaskClient <Flask 'app'>> def test_test_endpoint(client): response = client.get('/test') assert response.status_code == 200 > assert response.json == {1: "test"} E AssertionError: assert {'1': 'test'} == {1: 'test'} E E Left contains 1 more item: E {'1': 'test'} E Right contains 1 more item: E {1: 'test'} E Use -v to get more diff
原因解析
这不是Flask的特殊处理,而是JSON规范的硬性要求:JSON对象的键必须是字符串类型,不允许使用数字、布尔值等其他类型作为键。
当Flask返回字典时,底层会使用JSON序列化器(默认是Python标准库的json模块)将字典转换为JSON格式的字符串。这个序列化过程中,所有非字符串类型的键都会被自动转换为字符串,才能符合JSON规范。
而客户端(这里是Flask的测试客户端)解析JSON响应时,会把JSON中的字符串键还原为Python的字符串类型,所以最终得到的字典是{'1': 'test'},和代码中返回的{1: 'test'}自然不匹配。
解决方案
根据JSON规范调整代码即可,有两种常用方式:
方式一:直接使用字符串键返回
修改接口的返回字典,提前把键设为字符串,既符合规范,也能让测试通过:@app.route('/test', methods=['GET']) def test_endpoint(): return {"1": "test"}, 200同时把测试断言改为:
assert response.json == {"1": "test"}方式二:测试时适配字符串键
如果业务逻辑中必须保留整数键的定义,可以不修改接口代码,只调整测试断言,接受JSON规范下的字符串键结果:assert response.json == {"1": "test"}
内容的提问来源于stack exchange,提问作者Alexander McFarlane
相关产品推荐
相关产品推荐

