解析YAML文件转字典遇TypeError,求问题排查与解决方法
问题:YAML解析后环境项为长字符串,无法通过键名访问
我想把下面定义的YAML内容转换成字典:
development: user:dev_uid pass:dev_pwd host:127.0.0.1 database:dev_db production: user:uid pass:pwd host:127.0.0.2 database:db
我用YAML库加载数据后,发现字典里的环境项是长字符串。执行了这段代码:
#!/usr/bin/python3 import yaml config = yaml.load(open('database.conf', 'r')) print(config['development'])
输出结果是:
user:dev_uid pass:dev_pwd host:127.0.0.1 database:dev_db
根本没法通过键名访问条目,后来我尝试用yaml.load加载这个字符串也不行,执行print(config['development']['user'])的时候直接报错:
TypeError: string indices must be integers
我理想的情况是解析函数返回字典(或者可通过键名访问的结构),这样就能用print(config['development']['user'])甚至config.user这种方式访问内容了。请问我哪里出错了?
解答
嘿,这问题其实出在你的YAML格式完全不规范!YAML对缩进、冒号后的空格还有层级结构要求很严格,你把所有内容挤在一行,键值对之间既没换行也没正确分隔,导致YAML解析器直接把development后面的内容当成了一整段字符串,而不是嵌套的字典结构。
第一步:修正YAML文件格式
把database.conf改成符合规范的结构,每个键值对单独换行,冒号后必须加空格,子层级要缩进(一般用2个空格):
development: user: dev_uid pass: dev_pwd host: 127.0.0.1 database: dev_db production: user: uid pass: pwd host: 127.0.0.2 database: db
第二步:使用安全的加载方式
另外提醒下,yaml.load()是不安全的(可能执行恶意代码),推荐用yaml.safe_load()替代。修正后的Python代码:
#!/usr/bin/python3 import yaml # 用safe_load替代load,避免安全风险 with open('database.conf', 'r') as f: config = yaml.safe_load(f) # 现在就能正常通过键名访问了 print(config['development']['user']) # 输出 dev_uid
额外:实现dot运算符访问(可选)
如果想要用config.development.user这种dot方式访问,可以把字典转换成对象,比如用types.SimpleNamespace:
#!/usr/bin/python3 import yaml from types import SimpleNamespace def dict_to_namespace(d): if isinstance(d, dict): return SimpleNamespace(**{k: dict_to_namespace(v) for k, v in d.items()}) return d with open('database.conf', 'r') as f: config_dict = yaml.safe_load(f) config = dict_to_namespace(config_dict) print(config.development.user) # 输出 dev_uid
这样就能完全满足你的需求啦!
内容的提问来源于stack exchange,提问作者Shawn Taylor
相关产品推荐
相关产品推荐

