简化基于解析模块构建解析类型
radish-parse_type的Python项目详细描述
parse_type扩展了parse模块(与string.format()相反) 具有以下功能:
- build type converters for common use cases (enum/mapping, choice)
- build a type converter with a cardinality constraint (0..1, 0..*, 1..*) from the type converter with cardinality=1.
- compose a type converter from other type converters
- an extended parser that supports the CardinalityField naming schema and creates missing type variants (0..1, 0..*, 1..*) from the primary type converter
定义
- 类型转换器
- 转换文本表示的类型转换器函数 将值类型转换为此值类型的实例。 此外,类型转换器函数通常使用属性进行注释 这允许parse模块以通用方式使用它。 类型转换器也称为parse_type(此处使用的定义)。
- 基数字段
基数不同的相关类型的命名约定。 基数字段是字段格式的类型名后缀。 它允许解析格式表达式,ala:
"{person:Person}" #< Cardinality: 1 (one; the normal case) "{person:Person?}" #< Cardinality: 0..1 (zero or one = optional) "{persons:Person*}" #< Cardinality: 0..* (zero or more = many0) "{persons:Person+}" #< Cardinality: 1..* (one or more = many)
这个命名约定模仿了UML图中的关系描述。
基本示例
为数字(整数)定义自己的类型转换器:
# -- USE CASE:defparse_number(text):returnint(text)parse_number.pattern=r"\d+"# -- REGULAR EXPRESSION pattern for type.
这相当于:
importparse@parse.with_pattern(r"\d+")defparse_number(text):returnint(text)asserthasattr(parse_number,"pattern")assertparse_number.pattern==r"\d+"
# -- USE CASE: Use the type converter with the parse module.schema="Hello {number:Number}"parser=parse.Parser(schema,dict(Number=parse_number))result=parser.parse("Hello 42")assertresultisnotNone,"REQUIRE: text matches the schema."assertresult["number"]==42result=parser.parse("Hello XXX")assertresultisNone,"MISMATCH: text does not match the schema."
提示
上述功能是标准功能 在parse模块中。作为其余案例的介绍。
基数
为“manynumbers”创建类型转换器(列表,用逗号分隔) 基数为“1..*=1+”(many)的“number”的类型转换器。
# -- USE CASE: Create new type converter with a cardinality constraint.# CARDINALITY: many := one or more (1..*)fromparseimportParserfromparse_typeimportTypeBuilderparse_numbers=TypeBuilder.with_many(parse_number,listsep=",")schema="List: {numbers:ManyNumbers}"parser=Parser(schema,dict(ManyNumbers=parse_numbers))result=parser.parse("List: 1, 2, 3")assertresult["numbers"]==[1,2,3]
为基数为“0..1=”的“optionalnumbers”创建类型转换器。“。” (可选)从“数字”的类型转换器。
# -- USE CASE: Create new type converter with cardinality constraint.# CARDINALITY: optional := zero or one (0..1)fromparseimportParserfromparse_typeimportTypeBuilderparse_optional_number=TypeBuilder.with_optional(parse_number)schema="Optional: {number:OptionalNumber}"parser=Parser(schema,dict(OptionalNumber=parse_optional_number))result=parser.parse("Optional: 42")assertresult["number"]==42result=parser.parse("Optional: ")assertresult["number"]==None
枚举(名称到值映射)
根据 作为字典的映射。
# -- USE CASE: Create a type converter for an enumeration.fromparseimportParserfromparse_typeimportTypeBuilderparse_enum_yesno=TypeBuilder.make_enum({"yes":True,"no":False})parser=Parser("Answer: {answer:YesNo}",dict(YesNo=parse_enum_yesno))result=parser.parse("Answer: yes")assertresult["answer"]==True
根据 映射为枚举类(Python 3.4 enum或enum34) backport;另请参见:PEP-0435)。
# -- USE CASE: Create a type converter for enum34 enumeration class.# NOTE: Use Python 3.4 or enum34 backport.fromparseimportParserfromparse_typeimportTypeBuilderfromenumimportEnumclassColor(Enum):red=1green=2blue=3parse_enum_color=TypeBuilder.make_enum(Color)parser=Parser("Select: {color:Color}",dict(Color=parse_enum_color))result=parser.parse("Select: red")assertresult["color"]isColor.red
选项(名称枚举)
choice数据类型允许选择多个字符串中的一个。
为“choice”列表创建一个类型转换器,一个唯一名称列表 (作为字符串)。
fromparseimportParserfromparse_typeimportTypeBuilderparse_choice_yesno=TypeBuilder.make_choice(["yes","no"])schema="Answer: {answer:ChoiceYesNo}"parser=Parser(schema,dict(ChoiceYesNo=parse_choice_yesno))result=parser.parse("Answer: yes")assertresult["answer"]=="yes"
变量(类型替代品)
有时您需要一个类型转换器,它可以接受多个 类型转换器替代品。这通常被称为“变体”(或:联合)。
为“variant”类型创建一个类型转换器,该类型接受:
- Numbers (positive numbers, as integer)
- Color enum values (by name)
fromparseimportParser,with_patternfromparse_typeimportTypeBuilderfromenumimportEnumclassColor(Enum):red=1green=2blue=3@with_pattern(r"\d+")defparse_number(text):returnint(text)# -- MAKE VARIANT: Alternatives of different type converters.parse_color=TypeBuilder.make_enum(Color)parse_variant=TypeBuilder.make_variant([parse_number,parse_color])schema="Variant: {variant:Number_or_Color}"parser=Parser(schema,dict(Number_or_Color=parse_variant))# -- TEST VARIANT: With number, color and mismatch.result=parser.parse("Variant: 42")assertresult["variant"]==42result=parser.parse("Variant: blue")assertresult["variant"]isColor.blueresult=parser.parse("Variant: __MISMATCH__")assertnotresult
支持cardinalityfield的扩展解析器
解析器扩展了parse.Parser,并添加了以下功能:
- supports the CardinalityField naming scheme
- automatically creates missing type variants for types with a CardinalityField by using the primary type converter for cardinality=1
- extends the provide type converter dictionary with new type variants.
示例:
# -- USE CASE: Parser with CardinalityField support.# NOTE: Automatically adds missing type variants with CardinalityField part.# USE: parse_number() type converter from above.fromparse_type.cfparseimportParser# -- PREPARE: parser, adds missing type variant for cardinality 1..* (many)type_dict=dict(Number=parse_number)schema="List: {numbers:Number+}"parser=Parser(schema,type_dict)assert"Number+"intype_dict,"Created missing type variant based on: Number"# -- USE: parser.result=parser.parse("List: 1, 2, 3")assertresult["numbers"]==[1,2,3]