如何用Python先验证YAML格式有效性再校验多级Schema类型?
问题
使用yaml.safe_load()加载合法YAML后,通过schema库验证字段类型时,出现了不符合预期的错误输出。
原代码如下:
from schema import Use, Schema, SchemaError import yaml config_schema = Schema( { "pipeline": Use( str, error="Unsupported pipeline name. A string input is expected" ), "retry_parameters": Use( int, error="Unsupported retry strategy. An integer input is expected" ) }, error="A yaml file is expected" ) CONFIG = """ pipeline: 1 retry_parameters: 'pipe_1' """ configuration = yaml.safe_load(CONFIG) try: config_schema.validate(configuration) print("Configuration is valid.") except SchemaError as se: for error in se.errors: if error: print(error)
实际输出错误:
A yaml file is expected A yaml file is expected Unsupported retry strategy. A integer input is expected
预期输出错误:
Unsupported pipeline name. A string input is expected Unsupported retry strategy. A integer input is expected
需求:先验证YAML格式合法性,再检查每个键的类型是否符合预期,同时得到正确的错误提示。
解决方案
问题根源
原代码给顶层Schema设置的error="A yaml file is expected"会在每个字段验证失败时重复触发,因为字段验证不通过时,顶层Schema会判定整个结构不符合要求,导致重复输出该错误。另外,YAML格式的验证没有单独处理,应该先通过捕获yaml.YAMLError来判断格式合法性。
修正步骤
- 单独验证YAML格式:加载YAML时捕获
yaml.YAMLError,格式错误直接提示并终止流程。 - 移除顶层Schema的通用错误提示:避免字段验证失败时输出无关的重复错误,让字段级的自定义错误正常生效。
修正后的代码
from schema import Use, Schema, SchemaError import yaml config_schema = Schema( { "pipeline": Use( str, error="Unsupported pipeline name. A string input is expected" ), "retry_parameters": Use( int, error="Unsupported retry strategy. An integer input is expected" ) } # 移除顶层error参数,避免干扰字段级错误提示 ) CONFIG = """ pipeline: 1 retry_parameters: 'pipe_1' """ try: # 第一步:验证YAML格式合法性 configuration = yaml.safe_load(CONFIG) if configuration is None: # 处理空YAML内容的情况 print("Empty YAML content provided.") exit(1) except yaml.YAMLError as ye: print(f"Invalid YAML format: {ye}") exit(1) try: # 第二步:验证字段类型与结构 config_schema.validate(configuration) print("Configuration is valid.") except SchemaError as se: for error in se.errors: if error: print(error)
说明
- 先通过
try-except捕获yaml.YAMLError,确保只有合法YAML才进入后续字段验证环节。 - 移除顶层
Schema的error参数后,字段验证失败时只会输出对应的自定义错误,不会出现无关的重复提示。 - 增加空YAML判断(
yaml.safe_load加载空内容会返回None),避免后续验证出现异常。
内容的提问来源于stack exchange,提问作者Luiz
相关产品推荐
相关产品推荐

