从字典中简单地创建数据类。

dacite的Python项目详细描述


英安岩

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<61732f6461636974652e7376673f62716e63683d6d6173746572"/<<<<<<<<<<<<<<<<<<<<<<<<<

此模块简化了数据类的创建(pep 557) 从字典。

安装

要安装Dacite,只需使用pip

啊!

要求

dacite支持的最低python版本是3.6。

快速启动

啊!

功能

英安岩支持以下功能:

  • 嵌套结构
  • (基本)类型检查
  • 可选字段(即键入。可选
  • 联合体
  • 转发参考
  • 收藏
  • 自定义类型挂钩

动机

在函数或 方法不是一个好的实践。当然你可以创造 但是如果你只想 在单个对象中转到几个字段。

幸运的是,python对这个问题有一个很好的解决方案-数据类。 多亏了@dataclassdecorator,您可以轻松地创建一个新的自定义 以声明方式键入给定字段的列表。数据类 按设计支持类型提示。

但是,即使使用数据类,也必须创建 不知怎么的。在许多这样的情况下,你的输入是一本字典- 可以是来自http请求的有效负载,也可以是来自数据库的原始数据。如果 如果要将这些词典转换为数据类,dacite是 你最好的朋友。

这个库最初是为了简化后面类型的创建而创建的 数据传输对象(DTO),它可以跨越 应用程序架构。

必须指出,英安岩不是数据验证库。 有很多很棒的数据验证项目 可以在英安岩中复制此功能。如果你想的话 首先验证您的数据,您应该将英安岩与其中一个数据相结合 验证库。

请检查"用例"部分以获取真实的示例。

用法

英安岩基于单一功能-英安岩。/代码>。这个函数 采用3个参数:

  • 数据类-数据类类型
  • 数据-输入数据字典
  • 配置(可选)-创建过程的配置,实例 类

配置是具有以下字段的(数据)类:

  • 键入挂钩
  • 转发参考资料
  • 检查类型
  • 严格

下面的示例显示了from dict函数的所有特性和用法 所有config参数中的一个。

嵌套结构

您可以使用嵌套字典传递数据,它将创建一个 结果:

@dataclassclassA:x:stry:int@dataclassclassB:a:Adata={'a':{'x':'test','y':1,}}result=from_dict(data_class=B,data=data)assertresult==B(a=A(x='test',y=1))

可选字段

当您的数据类有一个可选的字段时,您将不提供 输入此字段的数据,它将采用none值。

fromtypingimportOptional@dataclassclassA:x:stry:Optional[int]data={'x':'test',}result=from_dict(data_class=A,data=data)assertresult==A(x='test',y=None)

接头

如果您的字段可以接受多种类型,则应使用union。英安 将尝试逐个将数据与提供的类型匹配。如果没有 match,它将引发unionmatcherror异常。

fromtypingimportUnion@dataclassclassA:x:str@dataclassclassB:y:int@dataclassclassC:u:Union[A,B]data={'u':{'y':1,},}result=from_dict(data_class=C,data=data)assertresult==C(u=B(y=1))

收藏

Dacite支持定义为集合的字段。它对两者都有效-基本 类型和数据类。

@dataclassclassA:x:stry:int@dataclassclassB:a_list:List[A]data={'a_list':[{'x':'test1','y':1,},{'x':'test2','y':2,}],}result=from_dict(data_class=B,data=data)assertresult==B(a_list=[A(x='test1',y=1),A(x='test2',y=2)])

类型挂钩

如果要转换输入,可以使用config.type_hooks参数 具有给定类型的数据类字段的数据放入新值中。你必须 传递以下映射:{type:callable},其中callable可调用[[任意],任意]

@dataclassclassA:x:strdata={'x':'TEST',}result=from_dict(data_class=A,data=data,config=Config(type_hooks={str:str.lower}))assertresult==A(x='test')

如果数据类字段类型是a可选[t]则可以同时传递- 可选[t]或只是t-作为输入钩子的键。与泛型相同 集合,例如,当一个字段具有list[t]类型时,您可以使用list[t]来 转换整个集合或转换每个项目。

转发参考

转发引用的定义可以作为{'name':type}映射传递到 配置转发引用。这个dict被传递给typing.get_type_hints()作为 globalnsparam计算每个字段的类型时。

@dataclassclassX:y:"Y"@dataclassclassY:s:strdata=from_dict(X,{"y":{"s":"text"}},Config(forward_references={"Y":Y}))assertdata==X(Y("text"))

类型检查

当内置类型检查器无法验证 您的类型(例如自定义泛型类)或具有这样的功能 被其他库覆盖,您不想验证您的类型两次。 在这种情况下,您可以使用config(check_types=false)禁用类型检查。 默认情况下,类型检查处于启用状态。

T=TypeVar('T')classX(Generic[T]):pass@dataclassclassA:x:X[str]x=X[str]()assertfrom_dict(A,{'x':x},config=Config(check_types=False))==A(x=x)

严格模式

默认情况下,from_dict忽略其他键(与数据类字段不匹配) 在输入数据中。如果要将此行为集config.strict更改为 true。如果dict中出现意外的key将引发unexpecteddataerror 例外。

例外情况

每当出现问题时,dict中的将引发足够的 例外。其中有一些:

  • 错误类型错误-当输入值的类型不匹配时引发 使用数据类字段的类型
  • missingvalueerror-未提供 必需字段
  • unionmatcherror-当提供的数据与任何类型不匹配时引发 联合的
  • forwardreferenceerror-在中遇到未定义的前向引用时引发 数据类
  • unexpecteddataerror-当启用strict模式并且输入 数据没有匹配的键

开发

首先-如果你想提交你的请求,非常感谢! 非常感谢您的支持。

请记住,每一个新功能、错误修复或改进都应该进行测试。 100%代码覆盖率是必须有。

我们正在使用一些静态代码分析工具来提高代码质量 (黑色mypypylint)。请确保您没有生成任何 提交PR之前出现错误/警告。您可以找到当前配置 在.travis.yml文件中。

最后但并非最不重要的是,如果你想介绍新功能,请讨论一下 第一个问题。

如何启动

克隆英安岩

$ pip install dacite
0

按照您喜欢的方式创建并激活virtualenv:

$ pip install dacite
1

安装所有Dacite依赖项:

$ pip install dacite
2

要运行测试,您只需启动:

$ pip install dacite
3

用例

当我们接收"原始"数据(python dict)作为 我们的系统。http请求负载是一个非常常见的用例。在大多数网络中 框架我们接收请求数据作为一个简单的字典。而不是 把这段话传给你的"业务"代码,这是个好主意 更"健壮"的东西。

下面的示例是一个简单的flask应用程序-它有一个端点。 您可以使用此端点在系统中"创建"产品。我们的核心 创建产品函数需要数据类作为参数。感谢英安岩 我们可以轻松地从post请求负载构建这样的数据类。

$ pip install dacite
4

如果我们想验证我们的数据(例如检查code是否有6个字符),该怎么办? 这些特征超出了英安岩的范围,但我们可以很容易地将其与 数据验证库之一。我们试试看 棉花糖

首先,我们必须定义数据验证模式:

$ pip install dacite
5

并在端点内使用它们:

$ pip install dacite
6

仍然英安岩帮助我们从"原始"dict创建数据类,其中包含已验证的数据。

作者

创建人:konrad ha_as

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java JPA。Eclipselink没有为mySQL提供密码,但它应该提供   我的Servlet和@FormDataParam存在java问题   java将什么作为上下文参数传递到文件I/O方法中?   如果两个值相同,java无法找到其中一个单选按钮   java在变量和方法名中使用下划线   JavaSpringMVC单线程安全?   klazz类的java Arraylist(反射Api)   java如何在数字字符串中查找最频繁的数字?   JavaAPI设计:使数据更易于阅读与强制更多API调用   JavaHadoopMapReduceforGoogleWebGraph   java无法启动gauge API:Runner意外退出   java如何在bluemix上使用ibm工作负载调度器?   拉取一年中某一周特定日期的所有日期   java为什么是我的角节点。js应用程序将图像上传到S3� 邮递员正确上传时的符号?   在不使用任何第三方jar的情况下将文件从本地传输到linux系统(java代码)   java将现有文件夹复制到Eclipse工作区中新创建的项目中   Java中的regex RegExp帮助   当使用“系统”外观时,Java组合框setSelectedItem会出现故障   JavaASM:在类的方法中获取局部变量名和值