python库将python类实例(对象)转换为扁平的和嵌套的字典数据结构。将python对象转换为JSON格式非常有用,特别是对嵌套对象,因为JSON库不能很好地处理它们。

dictfier的Python项目详细描述


听写器

构建状态最新版本python versionslicense

dictifier是一个库,用于将python类实例(对象)转换/序列化为字典数据结构。在将python对象转换为json格式时非常有用,特别是对于嵌套对象,因为json库不能很好地处理它们

先决条件

python版本=2.7

安装

pipinstalldictfier

开始

将平面对象转换为dict
importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
# Output{'name':'Danish','age':24}

将嵌套对象转换为dict
importdictfierclassCourse(object):def__init__(self,code,name):self.code=codeself.name=nameclassStudent(object):def__init__(self,name,age,course):self.name=nameself.age=ageself.course=coursecourse=Course("CS201","Data Structures")student=Student("Danish",24,course)query=["name","age",{"course":["code","name",]}]std_info=dictfier.dictfy(student,query)print(std_info)
# Output{'name':'Danish','age':24,'course':{'code':'CS201','name':'Data Structures'}}

将嵌套有iterable对象的对象转换为dict
importdictfierclassCourse(object):def__init__(self,code,name):self.code=codeself.name=nameclassStudent(object):def__init__(self,name,age,courses):self.name=nameself.age=ageself.courses=coursescourse1=Course("CS201","Data Structures")course2=Course("CS205","Computer Networks")student=Student("Danish",24,[course1,course2])query=["name","age",{"courses":[["code","name",]]}]std_info=dictfier.dictfy(student,query)print(std_info)
# Output{'name':'Danish','age':24,'courses':[{'code':'CS201','name':'Data Structures'},{'code':'CS205','name':'Computer Networks'}]}

实例方法或可调用对象字段如何?

我们得到了一个好消息,dictifier可以使用返回值作为字段的callable s,这非常简单,您只需将"call=true"作为关键字参数传递给objfield api并将您的可调用字段添加到查询中。例如

importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agedefage_in_days(self):returnself.age*365student=Student("Danish",24)query=["name",{"age_in_days":dictfier.objfield("age_in_days",call=True)}]std_info=dictfier.dictfy(student,query)print(std_info)
# Output{'name':'Danish','age_in_days':8760}

还可以使用newfieldapi添加自定义字段。例如

pipinstalldictfier
0
pipinstalldictfier
1

如果我们想使用自定义字段上的object字段来进行一些计算呢?

还有一种方法可以做到这一点,dictifierapi提供了useobj钩子,用于钩子或拉取当前查询节点上的对象。要使用当前对象,只需定义一个接受单个参数(对象)的函数,并对该函数执行计算,然后返回结果,调用useobj并将定义的函数传递给它。

假设我们要用月来计算学生的年龄,用年来计算年龄字段中的学生对象的年龄。下面是我们如何使用useobj钩子来完成此操作。

pipinstalldictfier
2
pipinstalldictfier
3

如果要在自定义字段(重命名obj字段)上使用对象字段,该怎么办?

这可以通过两种方式实现,正如您可能已经猜到的,一种方法是通过传递返回要使用的字段值的函数来使用useobj钩子,另一种简单的方法是使用objfield钩子。就像useobjhook一样,objfieldhook用于钩住或拉取当前查询节点上的对象字段。要使用当前对象字段,只需调用objfield并传递要使用或替换的字段名即可。

假设我们想在结果中将年龄字段重命名为年龄。下面是我们如何使用objfield钩子来实现这一点。

pipinstalldictfier
4
pipinstalldictfier
5

如果您想使用useobj钩子,您可以这样做。

pipinstalldictfier
6
pipinstalldictfier
5

实际上,hook是通过useobj实现的,所以这两种方法都是sa我是性能的中间人,但我想你会同意我的看法,在这种情况下,objfield比useobj可读性更高。

您还可以查询由useobjhook返回的对象,这可以通过将查询作为第二个参数传递给useobj或使用'query=your_query'作为kwarg来完成。例如

pipinstalldictfier
8
pipinstalldictfier
9

对于iterable对象,您可以这样做。

importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
0
importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
1

听写器是如何工作的?

dictifier通过递归地将给定对象转换为相应的dict来工作(因此可以在嵌套对象上工作)通过使用查询来工作。因此,重要的是知道如何构造正确的查询,以便从对象中提取正确的数据。

有什么问题吗?

查询基本上是一个模板,它告诉dictifier从对象中提取什么。它定义为要提取的对象字段的列表或元组。

样本转换。

使用下面的查询查询平面学生对象时

importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
2

听写器将把它转换成

importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
3

对于嵌套查询,它类似于

importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
4

对应的dict

importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
5

对于iterable对象,它是这样的

importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
6

将列表或元组放入对象字段的列表或元组中是声明对象可iterable的一种方法。在这种情况下

importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
7

对应的dict

importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
8

注意"courses"上的列表或元组与"name"和"age"等其他字段不同,它使"courses"变为可访问的,这就是在"courses"查询中嵌套列表或元组的原因。

很简单吧?

如果我想定制听写器的工作原理呢?

你可能会遇到这样的情况:你必须改变听写器的工作方式,才能得到你想要的结果,别担心我们会支持你。dictifier是高度可配置的,它允许您配置如何将每种类型的对象转换为字典数据结构。听写器配置分为三个部分,分别是

  • 平面对象配置(pass flat_obj=function kwarg to dictfy)

  • 嵌套平面对象配置(传递嵌套平面对象=函数Kwarg到dictfy)

  • 嵌套iterable objects config(将嵌套iter obj=函数kwarg传递给dictfy)

在上述所有情况下,分配给flat_obj、nested_flat_obj或nested_iter_obj的函数都接受三个位置参数,即字段值(object)、父对象和字段名。现在考虑一个简单的orm示例,它有两个关系多个一个用于显示对象之间的关系。

importdictfierclassStudent(object):def__init__(self,name,age):self.name=nameself.age=agestudent=Student("Danish",24)query=["name","age"]std_info=dictfier.dictfy(student,query)print(std_info)
9
# Output{'name':'Danish','age':24}
0

从上面的示例中,如果您想返回嵌套平面或嵌套可iterable对象(在api设计和序列化模型中非常常见)的主键(pk),您可以按如下方式执行。

# Output{'name':'Danish','age':24}
1
# Output{'name':'Danish','age':24}
2

投稿prs welcome

我欢迎所有的贡献。请先阅读contribution.md。您可以提交任何想法,如拉取请求或github问题。如果您想改进代码,请查看代码风格指南,祝您愉快!

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

推荐PyPI第三方库


热门话题
java Jgit对于给定的存储库,我们如何确定新提交的列表,以及每个提交来自哪个分支?   从MS Access数据库添加java ComboBoxItem   如何禁止Java列表中不同类的实例?   java在没有Web的JAXR上使用Shiro过滤器。xml   由于java原因,无法在Ubuntu上安装Netbeans 8.2。awt。未找到恐怖和辅助技术   java JUnit对RuntimeException的处理(特别是)   java空集合在Apache CXF服务(JAXWS)中被转换为null   java CannotAcquireLockException问题   sql如何在数据库中对(Java)枚举建模(使用SQL92)   安卓在Java中获取友好url后面的文件名   java如何访问数组名以获取列表?   javascript Java Nashorn longBitsToDouble   java控制台<init>错误   java将一个LinkedList追加/连接到另一个LinkedList的最有效方式是什么?   Java for正在跳过的循环   java帮助创建带有动画的复杂Swing GUI   java Android编辑文本。setHint在片段中不工作