gpt4 book ai didi

python - eval vs json转换和解析像字符串这样的字典

转载 作者:太空宇宙 更新时间:2023-11-04 03:10:06 26 4
gpt4 key购买 nike

自从我上一个 python 项目以来已经有一段时间了,所以我有点生疏了——请随时提供任何适当的建议或批评——所以我有几个关于 eval 和 JSON 的问题。

对于这个项目,我仅限于 Python 2.6 默认库——我试图解析用于 LDAP 身份验证的基于 Linux 的专有应用程序的数据库内容。用于查询数据库的特定命令并不严格重要,但我使用以下方法返回包含的输出:

process = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE)
stdout = process.communicate()[0]

输出:

[{'header_obj_idx': 32,
'header_obj_state': 2,
'header_obj_type': 48,
'index': 2,
'name': '',
'obj_id': '8b14c165094d4cac81725227ce389277',
'ldap_data': '{"search_filter":"(sAMAccountName={username})","roles":["admin:CN=SuperUsers,DC=example,DC=com","read_only:CN=Users,DC=example,DC=com"],"search_base":"OU=Users,DC=example,DC=com","server_url":["ldap://ad.example.com","ldaps://ad.example.com:3001"],"user_to_dn_rule":"{username}@example.com","bind_dn":"CN=Bind,OU=Users,DC=example,DC=com","timeout":1500,"bind_pw":"xxxxxxxx","cache_expire":86400,"ca_cert_file":null}'},
{'header_obj_idx': 31,
'header_obj_state': 2,
'header_obj_type': 48,
'index': 1,
'name': '',
'obj_id': 'b0efc7a3d38a4f70abec4f73f69124de',
'ldap_data': '{"search_filter":"(sAMAccountName={username})","roles":["admin:CN=SuperUsers,DC=example,DC=com"],"search_base":"OU=Users,DC=example,DC=com","server_url":["ldap://169.254.0.1"],"user_to_dn_rule":null,"bind_dn":"CN=Bind,OU=Users,DC=example,DC=com","timeout":1500,"bind_pw":"xxxxxxxx","cache_expire":86400,"ca_cert_file":null}'}]

** 我看到一篇帖子指出 shell=True 可能具有某些安全隐患,想知道是否有更好的解决方案?

利用 ast.literal_evaljson.loads 我已经能够成功解析单个 key 对,但我觉得我的多级转换没有必要并相信可能有更好的方法?

def ldap_data(stdout):
# evaluate object and return usable 'ldap_data' as dictionary
_data = ast.literal_eval(stdout)[0]['ldap_data']
return json.loads(_data)

ldap_data(stdout)['roles']

最后,当我开始这个项目时,我从来没有想过用户可能有多个 ldap 配置,具体取决于个人部署需求,所以我从来没有真正考虑过如何解析每个字典实例。考虑到我在使用此解决方案时遇到的障碍数量,我希望有人可以帮助设计一个解决方案,以利用在上面的输出中找到的索引。

我很抱歉问了这么多,我确定我只是想多了一点,并期待了解我可以做些什么来改进。在此先感谢您的帮助!

最佳答案

通常,当使用 subprocess 运行单个命令时,如果您将命令名称和每个选项设为单独的字符串,则不需要 shell=True,即

['cmd', 'arg1', 'arg2']

确实需要shell=True 来执行 shell 内部的命令,或利用其他 shell 功能,如 the docs 中所述,但这不是问题。

至于解析该数据,您不需要 ast.literal_eval,但您确实需要修复引号以使该数据成为有效的 JSON。这可以通过转义现有的双引号,然后将单引号转换为双引号来完成。使用 json.loads 将修复的数据解析为 Python 列表后,您需要再次调用 json.loads 以提取 LDAP 字典。

import json

src = '''\
[{'header_obj_idx': 32,
'header_obj_state': 2,
'header_obj_type': 48,
'index': 2,
'name': '',
'obj_id': '8b14c165094d4cac81725227ce389277',
'ldap_data': '{"search_filter":"(sAMAccountName={username})","roles":["admin:CN=SuperUsers,DC=example,DC=com","read_only:CN=Users,DC=example,DC=com"],"search_base":"OU=Users,DC=example,DC=com","server_url":["ldap://ad.example.com","ldaps://ad.example.com:3001"],"user_to_dn_rule":"{username}@example.com","bind_dn":"CN=Bind,OU=Users,DC=example,DC=com","timeout":1500,"bind_pw":"xxxxxxxx","cache_expire":86400,"ca_cert_file":null}'},
{'header_obj_idx': 31,
'header_obj_state': 2,
'header_obj_type': 48,
'index': 1,
'name': '',
'obj_id': 'b0efc7a3d38a4f70abec4f73f69124de',
'ldap_data': '{"search_filter":"(sAMAccountName={username})","roles":["admin:CN=SuperUsers,DC=example,DC=com"],"search_base":"OU=Users,DC=example,DC=com","server_url":["ldap://169.254.0.1"],"user_to_dn_rule":null,"bind_dn":"CN=Bind,OU=Users,DC=example,DC=com","timeout":1500,"bind_pw":"xxxxxxxx","cache_expire":86400,"ca_cert_file":null}'}]
'''

#Escape existing double quotes, and then convert single quotes to double quotes
data = json.loads(src.replace('"', '\\"').replace("'", '"'))
for d in data:
ldap = json.loads(d['ldap_data'])
print json.dumps(ldap, indent=4, sort_keys=True), '\n'

输出

{
"bind_dn": "CN=Bind,OU=Users,DC=example,DC=com",
"bind_pw": "xxxxxxxx",
"ca_cert_file": null,
"cache_expire": 86400,
"roles": [
"admin:CN=SuperUsers,DC=example,DC=com",
"read_only:CN=Users,DC=example,DC=com"
],
"search_base": "OU=Users,DC=example,DC=com",
"search_filter": "(sAMAccountName={username})",
"server_url": [
"ldap://ad.example.com",
"ldaps://ad.example.com:3001"
],
"timeout": 1500,
"user_to_dn_rule": "{username}@example.com"
}

{
"bind_dn": "CN=Bind,OU=Users,DC=example,DC=com",
"bind_pw": "xxxxxxxx",
"ca_cert_file": null,
"cache_expire": 86400,
"roles": [
"admin:CN=SuperUsers,DC=example,DC=com"
],
"search_base": "OU=Users,DC=example,DC=com",
"search_filter": "(sAMAccountName={username})",
"server_url": [
"ldap://169.254.0.1"
],
"timeout": 1500,
"user_to_dn_rule": null
}

在 Python 2.6.6 上测试

请注意,ldap 字典中的键(和值字符串)是 Unicode 字符串,而那些在 JSON 转储中表示为 null 的值实际上是

关于python - eval vs json转换和解析像字符串这样的字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38321676/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com