跳转到主要内容

简化了基于parse模块构建parse类型的操作

项目描述

CI Build Status Latest Version License Downloads

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

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

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

    来自基数=1的类型转换器。

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

  • 一个支持基数字段命名约定的扩展解析器

    并从主要类型转换器创建缺失的类型变体(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 enumenum34 回滚;另请参阅: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]

项目详情


下载文件

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

源分发

parse_type-0.6.4.tar.gz (96.5 kB 查看散列)

上传时间

构建分发

parse_type-0.6.4-py2.py3-none-any.whl (27.4 kB 查看哈希值)

上传时间: Python 2 Python 3

由以下支持