跳转到主要内容

简化了基于parse模块构建解析类型的构建过程

项目描述

Travis CI Build Status Latest Version Downloads License

parse_type 扩展了 parse 模块(与 string.format() 相反)以下功能

  • 为常见用例构建类型转换器(枚举/映射,选择)

  • 从具有cardinality=1的类型转换器构建具有基数约束的类型转换器(0..1,0..*,1..*)

  • 从其他类型转换器组合类型转换器

  • 扩展解析器,支持CardinalityField命名规范,并从主类型转换器创建缺失的类型变体(0..1,0..*,1..*)

定义

类型转换器

一个将值类型的文本表示转换为该值类型实例的类型转换器函数。此外,类型转换器函数通常带有属性,允许 parse 模块以通用方式使用它。类型转换器也称为 parse_type(此处使用的定义)。

基数字段

用于相关类型(这些类型在基数上不同)的命名约定。基数字段是字段格式的类型名称后缀。它允许解析格式表达式,如

"{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:
def parse_number(text):
    return int(text)
parse_number.pattern = r"\d+"  # -- REGULAR EXPRESSION pattern for type.

这相当于

import parse

@parse.with_pattern(r"\d+")
def parse_number(text):
     return int(text)
assert hasattr(parse_number, "pattern")
assert parse_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")
assert result is not None, "REQUIRE: text matches the schema."
assert result["number"] == 42

result = parser.parse("Hello XXX")
assert result is None, "MISMATCH: text does not match the schema."

基数

从“Number”类型转换器创建一个用于“ManyNumbers”的类型转换器(列表,以逗号分隔),基数“1..* = 1+”(多个)。

# -- USE CASE: Create new type converter with a cardinality constraint.
# CARDINALITY: many := one or more (1..*)
from parse import Parser
from parse_type import TypeBuilder
parse_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")
assert result["numbers"] == [1, 2, 3]

从“Number”类型转换器创建一个用于“OptionalNumbers”的类型转换器,基数“0..1 = ?”(可选)。

# -- USE CASE: Create new type converter with cardinality constraint.
# CARDINALITY: optional := zero or one (0..1)
from parse import Parser
from parse_type import TypeBuilder

parse_optional_number = TypeBuilder.with_optional(parse_number)
schema = "Optional: {number:OptionalNumber}"
parser = Parser(schema, dict(OptionalNumber=parse_optional_number))
result = parser.parse("Optional: 42")
assert result["number"] == 42
result = parser.parse("Optional: ")
assert result["number"] == None

枚举(名称到值的映射)

从映射描述作为字典创建一个“枚举”类型转换器。

# -- USE CASE: Create a type converter for an enumeration.
from parse import Parser
from parse_type import TypeBuilder

parse_enum_yesno = TypeBuilder.make_enum({"yes": True, "no": False})
parser = Parser("Answer: {answer:YesNo}", dict(YesNo=parse_enum_yesno))
result = parser.parse("Answer: yes")
assert result["answer"] == True

从映射描述作为枚举类创建一个“枚举”类型转换器(Python 3.4 enum 或 enum34 迁移;参见:PEP-0435)。

# -- USE CASE: Create a type converter for enum34 enumeration class.
# NOTE: Use Python 3.4 or enum34 backport.
from parse import Parser
from parse_type import TypeBuilder
from enum import Enum

class Color(Enum):
    red   = 1
    green = 2
    blue  = 3

parse_enum_color = TypeBuilder.make_enum(Color)
parser = Parser("Select: {color:Color}", dict(Color=parse_enum_color))
result = parser.parse("Select: red")
assert result["color"] is Color.red

选择(名称枚举)

选择数据类型允许选择多个字符串中的一个。

创建一个“Choice”列表的类型转换器,一个唯一的名称列表(作为字符串)。

from parse import Parser
from parse_type import TypeBuilder

parse_choice_yesno = TypeBuilder.make_choice(["yes", "no"])
schema = "Answer: {answer:ChoiceYesNo}"
parser = Parser(schema, dict(ChoiceYesNo=parse_choice_yesno))
result = parser.parse("Answer: yes")
assert result["answer"] == "yes"

变体(类型替代)

有时你需要一个可以接受多种类型转换器替代文本的类型转换器。这通常称为“变体”(或:联合)。

创建一个可以接受以下内容的“Variant”类型转换器

  • 数字(正数,作为整数)

  • 颜色枚举值(按名称)

from parse import Parser, with_pattern
from parse_type import TypeBuilder
from enum import Enum

class Color(Enum):
    red   = 1
    green = 2
    blue  = 3

@with_pattern(r"\d+")
def parse_number(text):
    return int(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")
assert result["variant"] == 42
result = parser.parse("Variant: blue")
assert result["variant"] is Color.blue
result = parser.parse("Variant: __MISMATCH__")
assert not result

扩展解析器,支持基数字段支持

解析器扩展了 parse.Parser 并添加以下功能

  • 支持基数字段命名方案

  • 自动使用基数=1的主要类型转换器为具有基数字段的类型创建缺失的类型变体

  • 扩展提供类型转换器字典以包含新的类型变体。

示例

# -- USE CASE: Parser with CardinalityField support.
# NOTE: Automatically adds missing type variants with CardinalityField part.
# USE:  parse_number() type converter from above.
from parse_type.cfparse import Parser

# -- 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+" in type_dict, "Created missing type variant based on: Number"

# -- USE: parser.
result = parser.parse("List: 1, 2, 3")
assert result["numbers"] == [1, 2, 3]

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解更多关于 安装软件包 的信息。

源代码发行版

radish-parse_type-0.3.5.tar.gz (263.0 kB 查看哈希)

上传时间 源代码

构建发行版

radish_parse_type-0.3.5-py2-none-any.whl (240.0 kB 查看哈希)

上传时间 Python 2

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面