Python将JSON作为字符串而不是文本返回,对此感到困惑
我在RoR和Rails中做了一些编码,当我通过API调用返回JSON对象时,它返回为Python将JSON作为字符串而不是文本返回,对此感到困惑,python,json,api,flask,flask-sqlalchemy,Python,Json,Api,Flask,Flask Sqlalchemy,我在RoR和Rails中做了一些编码,当我通过API调用返回JSON对象时,它返回为 {“id”:“1”,“name”:“Dan”} 然而,在Python中(使用Flask和Flask SQLAlchemy),当我通过JSON.dumps或jsonpickle.encode返回JSON对象时,它返回为 “{\“id\”:“1\”,““name\”:“Dan\”}”这看起来非常笨拙,因为它无法在另一端轻松解析(在本例中是通过iOS应用程序-Obj-C) 我在这里遗漏了什么,我应该怎么做才能将其作为
{“id”:“1”,“name”:“Dan”}
然而,在Python中(使用Flask和Flask SQLAlchemy),当我通过JSON.dumps或jsonpickle.encode返回JSON对象时,它返回为
“{\“id\”:“1\”,““name\”:“Dan\”}”
这看起来非常笨拙,因为它无法在另一端轻松解析(在本例中是通过iOS应用程序-Obj-C)
我在这里遗漏了什么,我应该怎么做才能将其作为JSON文本而不是JSON字符串返回
这就是我的代码的样子:
people = models.UserRelationships.query.filter_by(user_id=user_id, active=ACTIVE_RECORD)
friends = people.filter_by(friends=YES)
json_object = jsonpickle.encode(friends.first().as_dict(), unpicklable=False, keys=True)
print(json_object) # this prints here, i.e. { "id" : "1", "name" : "Dan" }
return json_object # this returns "{ \"id\" : \"1\", \"name\": \"Dan\" }" to the browser
看起来您正在使用Django,在这种情况下,请执行以下操作
from django.utils import simplejson as json
...
return HttpResponse(json.dumps(friends.first().as_dict()))
这几乎总是一个迹象,表明您正在对某个地方的数据进行双重编码。例如:
>>> obj = { "id" : "1", "name" : "Dan" }
>>> j = json.dumps(obj)
>>> jj = json.dumps(j)
>>> print(obj)
{'id': '1', 'name': 'Dan'}
>>> print(j)
{"id": "1", "name": "Dan"}
>>> print(jj)
"{\"id\": \"1\", \"name\": \"Dan\"}"
这里,jj
是一个完全有效的JSON字符串表示,但它不是obj
的表示,它是字符串j
的表示,这是无用的
通常你不会直接这么做;相反,您首先使用JSON字符串而不是对象(例如,您从客户端请求或文本文件获得它),或者调用库中的某个函数,如
requests
或jsonpickle
,该函数使用已编码的字符串隐式调用JSON.dumps
。但无论哪种方式,问题都是一样的,解决方案都是一样的:只是不要双重编码。在您的理解中缺少的是,当您在Python中使用JSON模块时,您没有使用JSON对象。根据定义,JSON只是一个符合特定标准的字符串
假设您拥有字符串:
friends = '{"name": "Fred", "id": 1}'
如果要在python中使用此数据,则需要将其加载到python对象中:
import json
friends_obj = json.loads(friends)
此时,friends_obj是一本python词典
如果您想转换它(或任何其他python字典或列表),那么json.dumps就在这里派上了用场:
friends_str = json.dumps(friends_obj)
print friends_str
'{"name": "Fred", "id": 1}'
但是,如果我们尝试“转储”原始好友字符串,您将看到不同的结果:
dumped_str = json.dumps(friends)
print dumped_str
'"{\\"name\\": \\"Fred\\", \\"id\\": 1}"'
这是因为您基本上是在尝试将普通字符串编码为JSON,它正在转义字符。我希望这有助于理解事情
干杯您应该使用
flask.jsonify
,它不仅可以正确编码,还可以相应地设置内容类型
标题
people = models.UserRelationships.query.filter_by(user_id=user_id, active=ACTIVE_RECORD)
friends = people.filter_by(friends=YES)
return jsonify(friends.first().as_dict())
json.dumps将返回对象的字符串表示形式。请参阅帮助(json.dumps)->将
obj
序列化为json格式的str
。如果需要json,应使用相关模块将其序列化为json。打印某些内容不会将其转换为JSON。JSON文本是一个字符串。JSON是一种符号。JSON只能是字符序列。您将数据结构与其表示形式混淆。您显示的代码不可能实现您所声称的功能json\u object=print(json\u object)
将json\u object
设置为None
。是的,你是对的。我写代码太快了!很抱歉我在上面编辑过。问题是当我将它返回到浏览器时,而不是打印它时。我没有使用Django,所以我想我不能使用HttpResponse?我正在使用Python,Flask,Flask SQLAlchemy..啊,对不起,我下结论了;有些语法看起来像Django,但不是。Django是模块化的,所以如果您愿意,您可以使用一些,但如果您使用的是Flask,您可能不需要。我在转换为dict的Flask SQLAlchemy行上使用jsonpickle.encode(即jsonpickle.encode(friends.first().as_dict(),unpicklable=False,keys=True)
)所以它可能还不是一个编码的字符串,除非我误解了什么。@Dan:你从哪里返回这个?你的应用程序是如何配置的?如果Flask希望您给它一个将要编码的对象,而您给它编码一个对象并给它结果字符串,它将以双重编码结束。@Dan:作为旁注,为什么您要使用jsonpickle
而不是stdlibjson
模块,或者Flask的内置jsonify
?jsonpickle
的全部要点是,它为您提供了一种包装和展开Python类型(如自定义类)的方法,这些类型不会直接映射到JSON,除非另一方也在使用jsonpickle
,而web浏览器或ObjC应用程序显然不是。您是对的。这是我的问题:/I我应该使用jsonify。谢谢,问题不在于打印。当打印出来时,它是可以的,当我将它返回到浏览器时,它是双重编码的。i、 e.返回json\u对象#这将向浏览器返回“{\“id\”:“1\”,“name\”:“Dan\”}”
,谢谢!我的问题是无法理解http响应和JSON字符串之间的区别。在将http响应用于API时,我需要它。