如何将含AnyUrl类型的Pydantic模型实例导出为字符串形式YAML
解决Pydantic AnyUrl类型序列化为YAML时输出URL字符串的问题
你遇到的问题是Pydantic的AnyUrl字段在序列化为YAML时,会被展开成包含内部结构的Python对象,而非直接输出URL字符串。以下是几种可行的解决方法:
方法1:先转JSON再转YAML
利用Pydantic默认的JSON序列化会将AnyUrl转为字符串的特性,先把模型转为JSON,再解析为字典后生成YAML:
from pydantic import BaseModel, AnyUrl import yaml import json class MyModel(BaseModel): url: AnyUrl data = {'url': 'https://www.example.com'} model = MyModel.parse_obj(data) # 先序列化到JSON,再转为字典后生成YAML json_str = model.json() data_dict = json.loads(json_str) y = yaml.dump(data_dict, indent=4) print(y)
输出结果:
url: https://www.example.com
方法2:自定义PyYAML的序列化器
给PyYAML添加针对AnyUrl类型的自定义序列化规则,直接将其转为字符串输出:
from pydantic import BaseModel, AnyUrl import yaml # 定义AnyUrl的YAML序列化逻辑 def anyurl_representer(dumper, data): return dumper.represent_str(str(data)) # 注册序列化器 yaml.add_representer(AnyUrl, anyurl_representer) class MyModel(BaseModel): url: AnyUrl data = {'url': 'https://www.example.com'} model = MyModel.parse_obj(data) y = yaml.dump(model.dict(), indent=4) print(y)
此方法会直接输出纯URL字符串,无需额外转换步骤。
方法3:Pydantic v2+ 专用:使用serialize_as_primitive参数
如果你使用的是Pydantic v2版本,可通过model_dump()方法的serialize_as_primitive参数,让AnyUrl以原始字符串形式输出:
from pydantic import BaseModel, AnyUrl import yaml class MyModel(BaseModel): url: AnyUrl data = {'url': 'https://www.example.com'} model = MyModel.model_validate(data) # 启用原始类型序列化 y = yaml.dump(model.model_dump(serialize_as_primitive=True), indent=4) print(y)
为什么重写__repr__无效?
PyYAML序列化对象时,并非依赖__repr__方法,而是根据对象的类型匹配对应的序列化逻辑。直接重写__repr__无法改变PyYAML对AnyUrl类型的处理方式,因此需要通过上述方法自定义序列化规则。
内容的提问来源于stack exchange,提问作者morfys
相关产品推荐
相关产品推荐

