获取 JSON 的 str 表示以像 print() 一样进行编码

Posted

技术标签:

【中文标题】获取 JSON 的 str 表示以像 print() 一样进行编码【英文标题】:Get str representation of JSON to encode like print() 【发布时间】:2021-12-07 16:47:47 【问题描述】:

我需要将如下所示的 JSON 对象传递给 REST API(请注意值中转义的 " - 即字符串格式的 json)

 "data": "\"positionname\": \"API User\",\"person\": \"Paul\"," 

在 POSTMAN 中,使用 POST 方法到 API 端点和上面的 JSON,我得到 200 并创建了一条记录。当我尝试使用“请求”从 Python Shell 执行相同操作时,它失败了:

# JSON as string with proper escape
>>> data = '"data": "\\"positionname\\": \\"API User\\", \\"person\\": \\"Paul\\""'
# Loads output removes backslashes
>>> json.loads(data)
'data': '"positionname": "API User", "person": "Paul"'
# Print output shows data -exactly- as I need to pass it to the API
# The string that print() provides is in the EXACT format that the API requires
# It needs " around data, and the escape \ character is needed.
>>> print (data)
"data": "\"positionname\": \"API User\", \"person\": \"Paul\""
# Data still in original format...
>>> data
'"data": "\\"positionname\\": \\"API User\\", \\"person\\": \\"Paul\\""'
# Try to pass the data to the API..
>>> response = apiRequest.post('http://apiURL/board/Input', data)
# It fails...
>>> response<Response [400]>
>>> 

更新:

我能够使用 POSTMAN 使用单引号添加记录,如下所示。但是,当我在 Python 中尝试时,“数据”键更改为“数据”(单引号)并且 API 需要双引号:

# Now using single quotes in the JSON - sending this to POSTMAN works
>>> data = '"data": "\'positionname\': \'API User\', \'person\': \'X\'"'

# Data still looks great.
>>> data
'"data": "\'positionname\': \'API User\', \'person\': \'X\'"'

# But when I send to the API, I get an error saying that double-quotes are required at the first character - that was odd b/c they are - but when I do a json.loads() I see that the "data" is now 'data'

Error:
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

>>> json.loads(data)
'data': "'positionname': 'API User', 'person': 'X'"

^^^ 为什么 'data' 是单引号,而 value 是 "" 双引号?

【问题讨论】:

试试 repr 或 str,虽然不清楚你想要什么 REST 服务要求数据看起来完全像: "data" : " \"positionname\": \"API User\", \"person\": \"Ted\" " 而且我无法正确转义反斜杠。 repr 复制反斜杠。 str 不会转义双反斜杠。并且 json.loads() 只是将它们完全删除。 print(data) 完美地格式化它,但没有办法捕获该输出。我试过 StringIO() 但没有运气。 换一种说法...为什么这样做: json.loads(' "data": "\\"positionname\\": \\"API User\\",\\" person\\": \\"Paul\\"," ') 创建这个输出: 'data': '"positionname": "API User","person": "Paul",' 为什么\\ 不是作为单个反斜杠 \ 输出吗? 【参考方案1】:

您不需要“捕获”print() 的输出;您已经拥有数据。

print() 打印 实际存在的实际数据,这与以 Python 语法编码的数据的 repr()esentation 不同。

类似地,file.write(yourdata)socket.send(yourdata) 之类的调用将发送该文字数据,而不是其 Python 表示形式。


如果它在您的控制范围内,您用来生成字符串的逻辑应该如下所示:

content =  "positionname": "API User", "person": "Paul" 
wrapper =  "data": json.dumps(content) 
wrapper_json = json.dumps(wrapper)

...如果您print(wrapper_json),您会看到格式正确的内容发送到您的服务。


我们可以通过发布到公开可用的 pastebin 并检索其响应来证明上述内容:

import requests, json, sys

position = "API User"
username = "Paul"

## FIXME: CHANGE THIS TO YOUR OWN PUBLIC REQUESTBIN INSTANCE
requestbin = 'https://enh4cydill4ac.x.pipedream.net'

content =  "positionname": position, "person": username 
wrapper =  "data": json.dumps(content) 
wrapper_json = json.dumps(wrapper)

response = requests.post(requestbin,
                         data=wrapper_json,
                         headers="Content-Type": "application/json")

向requestbin询问这个请求的原始正文,它告诉我们客户端发送给服务器的文本是:

"data": "\"positionname\": \"API User\", \"person\": \"Paul\""

...这正是我们所期望的。

【讨论】:

【参考方案2】:

您的用例看起来很奇怪,但如果您没有找到任何令人满意的解决方案,您可以尝试这样做以获得所需的输出。

data = ' "data": "\\"positionname\\": \\"API User\\",\\"person\\": \\"Paul\\"," '

dataSplitted = data.split("\\")

output = ""

for word in dataSplitted:
    output = "\".format(output, word)

output = output[1:]

【讨论】:

谢谢,但这也没有用。上面更新中的新问题。不确定 JSON 中的双引号是否会转换为单引号。

以上是关于获取 JSON 的 str 表示以像 print() 一样进行编码的主要内容,如果未能解决你的问题,请参考以下文章

从数组中解析字符串。错误代码:“json”没有属性“str”

如何使用str.replace解析此JSON数据?

R栅格:以像元值为条件的范围

json.dumps与json.loads实例

14.json文件读取

python基础3-json操作