小库,用于将python对象表示为dict
dehydrate的Python项目详细描述
动机
你为什么需要这样的图书馆?一个明显的用例是 有方法的复杂对象,大量的属性等等 序列化(到json/yaml/xml/pickle/whatever)。你可以控制 通过描述如何从对象中获取值以及如何 用简单的语法以脱水结构表示。
示例
简单病例
在最简单的情况下,您只需要get object,列出想要的属性 并根据属性名和它们的值使用键进行映射。 在这种情况下使用dehydrate快捷方式:
>>> from dehydrate import dehydrate >>> from pretend import stub as Person >>> iron_man = Person(first_name='Tony', login='iron_man') >>> dehydrated = dehydrate(obj=iron_man, specs=('first_name', 'login')) >>> sorted(dehydrated.items()) [('first_name', 'Tony'), ('login', 'iron_man')]
一些注释:
- 我在示例中使用dict的列表表示,因为它具有可预测性 其中项目的顺序。这很重要,因为这段代码是测试。
如果请求的属性名解析为对象的方法,则 调用它将在脱水的dict中设置。在Person类中,我们有方法 full_name,所以让我们尝试获取它的返回值:
>>> from dehydrate import dehydrate >>> from pretend import stub as Person >>> iron_man = Person(full_name=lambda: 'Tony Stark') >>> dehydrated = dehydrate(obj=iron_man, specs=('full_name',)) >>> sorted(dehydrated.items()) [('full_name', 'Tony Stark')]
但是如果您想将first_name属性放入结果的name键中呢 迪克特?只要指定specs(spec中的两个字符串可以是一个对象或 二元组):
>>> from dehydrate import dehydrate >>> from pretend import stub as Person >>> iron_man = Person(first_name='Tony', login='iron_man') >>> dehydrated = dehydrate(obj=iron_man, specs=( ... ('first_name', 'name'), ... 'login', ... )) >>> sorted(dehydrated.items()) [('login', 'iron_man'), ('name', 'Tony')]
第二个自变量总是被用作键,如果存在于规格
更复杂的情况
有时你会想在脱水的dict中增加一些价值,而不是 脱水对象的属性。或者您可能不想使用属性并添加一些 而是对这个元素的另一个处理。在我们的例子中,我们创建 为此调用的特殊类PersonDehydrator(继承自 dehydrate.Dehydrator)并在其上设置一些方法:
>>> from pretend import stub as Person >>> from examples import PersonDehydrator >>> iron_man = Person(password='iRon42', login='iron_man') >>> dehydrated = PersonDehydrator(specs=( ... 'password', ... ('superhero_status', 'is_superhero'), ... )).dehydrate(obj=iron_man) >>> sorted(dehydrated.items()) [('is_superhero', True), ('password', '******')]
在示例中,您可以看到,该对象具有password属性,但是 PersonDehydrator的get_password用于password规范。也可以 注意,调用get_superhero_status的结果是在key中设置的 is_superhero,因为规范中的第二项已声明。 可以使用脱水器类的属性声明specs。 或者通过将参数传入其__init__方法。
注意:
- 在文档中,我将引用examplespackage,您可以在repo中找到它。
递归脱水
lib最有价值的特性是,您可以描述如何递归地 使对象上的复杂字段脱水:
>>> from dehydrate import dehydrate, S >>> from pretend import stub as Person >>> from examples import PersonDehydrator >>> octopus = Person(login='octopus') >>> spider_man = Person(login='spidey', archenemy=octopus) >>> dehydrated = dehydrate( ... specs=( ... S('login'), ... S(target='archenemy', type='nested', specs=( ... S('login'), ... )), ... ), ... obj=spider_man ... ) >>> dehydrated['login'] 'spidey' >>> list(dehydrated['archenemy'].items()) [('login', 'octopus')]
可以看到,使用 dehydrate.Sshortcut(为了保持理智,还有简单的规范)。 可接受的参数是type='nested':
- target-name,描述如何从对象(或使用钩子)获取值 在脱水机上)
- dehydrator-类,可用于复杂目标的脱水 (dehydrate.Dehydrator默认)。
- specs-iterable,与上述结构相同(可选 如果你描述脱水器类的规格,但很有意义, 如果使用默认的Dehydratorclass)。
安装
简单:
pip install dehydrate
一定很好。
要求
- 六(我提到过Python3支持吗?我们有一个。)
理念
- 容易的事应该容易做。
- 复杂的事情必须是可能的。
测试
使用pytest库和纯pytest pep8 plugin编写的测试。 您应该运行python setup.py test以运行完整的测试套件或 coverage run --source=dehydrate setup.py test用于具有覆盖率的测试。 测试在Travis CI自动运行。文档中的示例还包括 由测试命令选择。
贡献
任何贡献都是受欢迎的。在github上使用fork/pull请求机制。
如果您添加了一些代码,那么您应该添加一些测试,以便覆盖主分支 应该一直是100%。有关更多说明,请参阅Testing部分。
让我从我的心脏:)。如果你纠正我的笨拙,我会很高兴的 文档和文档中的英语短语,甚至建议使用更合适的名称 对于代码中的变量。
待办事项
- 考虑给自己一个机会,把结果写在有序的字典里,而不是 简单指令。
- 添加关于所有内容的全面文档。
- 将带有类的复杂示例从自述文件移到文档中。
- 编写docstring并自动生成一些附加文档。
更改日志
0.3(2013-07-07)
- 嵌套脱水的新语法
0.2(2013-06-19)
- fields参数重命名为specs
- 改进的自述文件