如何在主方法外使用PyYAML从文本文件创建Python对象
解决PyYAML加载到自定义对象的问题
Hey,我看了你用PyYAML从文本文件创建自定义对象的代码,这里有几个需要调整的地方,我给你整理了修正后的版本,顺便解释下原因:
你的现有代码存在两个小问题:一是直接用yaml.load()有安全风险,二是加载后得到的是普通字典,不是你定义的config类实例,直接访问c.c肯定会报错。
修正后的目标对象类(config.py)
按照Python的PEP8规范,类名建议用大驼峰命名,这里我改成了Config,并且写了一个灵活的初始化方法:
class Config: def __init__(self, **kwargs): # 把YAML解析出来的所有键值对,自动设为实例属性 for key, value in kwargs.items(): setattr(self, key, value)
修正后的创建逻辑类(make_conf.py)
这里同样调整了类名,并且用更安全的文件操作和YAML加载方式:
from config import Config import yaml class MakeConf: def __init__(self): filename = 'configs.txt' # 用with语句打开文件,会自动帮你关闭,避免资源泄漏 with open(filename, 'r') as input_file: input_string = input_file.read() # 用safe_load替代load,防止恶意YAML执行危险代码 config_dict = yaml.safe_load(input_string) # 把字典转成Config类的实例 self.config = Config(**config_dict)
主方法代码
同样调整类名的引用,现在就能正常访问实例属性了:
from make_conf import MakeConf c = MakeConf().config print(c.c) # 只要你的configs.txt里有"c"这个配置项,就能正常输出
额外说明
- 关于
yaml.safe_load():除非你100%信任这个configs.txt的来源,否则绝对不要用yaml.load(),它可以执行任意Python代码,存在严重安全隐患。 - 关于
with语句:手动调用close()很容易忘记,用with上下文管理器会自动处理文件关闭,更稳妥。 - 动态属性设置:用
**kwargs和setattr的方式,不管你的YAML里有多少配置项,都能自动映射成Config实例的属性,扩展性更强。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

