Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python将JSON作为字符串而不是文本返回,对此感到困惑_Python_Json_Api_Flask_Flask Sqlalchemy - Fatal编程技术网

Python将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) 我在这里遗漏了什么,我应该怎么做才能将其作为

我在RoR和Rails中做了一些编码,当我通过API调用返回JSON对象时,它返回为

{“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
而不是stdlib
json
模块,或者Flask的内置
jsonify
jsonpickle
的全部要点是,它为您提供了一种包装和展开Python类型(如自定义类)的方法,这些类型不会直接映射到JSON,除非另一方也在使用
jsonpickle
,而web浏览器或ObjC应用程序显然不是。您是对的。这是我的问题:/I我应该使用jsonify。谢谢,问题不在于打印。当打印出来时,它是可以的,当我将它返回到浏览器时,它是双重编码的。i、 e.
返回json\u对象#这将向浏览器返回“{\“id\”:“1\”,“name\”:“Dan\”}”
,谢谢!我的问题是无法理解http响应和JSON字符串之间的区别。在将http响应用于API时,我需要它。