跳转到主要内容

可访问属性字典及其集合

项目描述

Travis CI build status PyPI Package latest release Supported versions Supported implementations Wheel packaging support Test line coverage

属性在许多情况下是最直接、最方便的访问复合数据的方式。 item.name 比字典典型的索引方式 item['name'] 更简洁、更易读、更简洁。拥有属性访问通常是能否直接轻松地解引用 item 的组件与决定为了清晰起见将此属性存储在完全不同的变量之间的区别 (item_name = item['name'])。

在遍历XML、JSON和其他通常嵌套的数据源中的数据结构时,简洁的直接访问可以显著简化代码。

Items

因此,items提供了方便的属性访问的 dict 子类 Item 以及辅助函数。

例如,itemize 帮助遍历字典序列,如JSON处理中常见的那样:每个记录都以 Item 的形式返回,而不是Python dict

典型的进展可能是从

for item in data:
    item_name = item['name']
    # ...
    print(item_name)

from items import itemize

for item in itemize(data):
    # ...
    print(item.name)

为了整体处理一个序列,返回一个 list

from items import itemize_all

itemize_all(data)

如果您正在迭代元组(或列表)序列而不是字典,您仍然可以通过提供要分配的字段名称来使用 itemize

parser = ...
for item in itemize(parser, fields='prefix token value'):
    if item.prefix is None and item.token == 'start_array':
        ...

在这里,每个由 parser(通常是 Python 生成器)返回的结果都被转换成一个 Item。现在您可以通过名称访问的方式方便地处理多个值,无需为这种结果类型创建单独的 namedtuple,也无需进行元组位置索引。

甚至可以对标量序列做这件事

for item in itemize('aeiou', fields='vowel')

item.value = 20 if item.vowel == 'e' else 15

除了优雅地处理单值序列之外,此示例还展示了每个 Item 的可变性。 namedtuple 作为返回类型很棒,但它们不能被后续处理轻松扩展或注释……这是许多算法的常见需求。

深入研究

Item 子类 collections.OrderedDict,因此键的顺序与程序首次遇到它们的顺序相同。在大多数开发环境中,有序映射的性能开销很小,尤其是在探索性和数据清理任务中。无论开销多大,都足以弥补没有键以看似随机的顺序出现时的编程和调试清晰性。

Item 还很宽容,就像 dict 和其变体通常所做的那样:如果您访问 item.some_attribute 而该属性不存在,您不会引发一个 KeyError,与典型的 Python 字典不同。相反,您会得到一个 Empty,一个指定的、类似于但与 None 不同的假值。这对于处理不规则或不均匀填充的数据很有用,因为您不需要始终如一的“保护条件”——if 语句或 try/except KeyError 块——以防止数据值缺失的情况。使用 Empty 而不是 None 可以保留在语义上重要的情况下使用 None 的能力。例如,在解析 JSON 时,JSON 的 null 值返回 None

Empty 对象是无限可解引用的。无论间接层级有多少,它们总是返回自身——相同的温和的“这里没有,不抛出异常”行为。您还可以迭代一个 Empty——它将简单地迭代零次。这巧妙地避免了在值可以是列表(或如果列表不存在,则为 None)的情况下常见的 TypeError: 'NoneType' object is not iterable 错误消息。

from items import Empty

e = Empty
assert e[1].method().there[33][0].no.attributes[99].here is Empty
for x in Empty:
    print('hey!')     # never prints, because no such iterations occur

有关 Empty 的更多背景信息,请参阅 nulltype 模块。典型用法如下

for item in itemize(data):
    if item.name:
        process(item)

缺少名称的项目将直接不进行处理。

您的数据结构越嵌套、越复杂、越不规则,这就越有价值。

序列化和反序列化

请小心导入数据。流行的用于读取 JSON、YAML 和其他格式的 Python 模块认为映射是有序的(或应该是有序的)。历史上和官方上,它们都不是有序的,无论它们看起来多么有序,无论其他语言(如 JavaScript)采用不同的方法,无论有多少 Stack Overflow 问题展示了有序输入和输出是多么强烈和广泛地被期望。因此,标准的输入/输出模块会在数据解析时导致混乱。采取步骤从它们返回有序映射。

# YAML module that will load into OrderedDict instances, which can then
# be easily converted to Item instances; based on default PyYAML
import oyaml as yaml
data = itemize_all(yaml.load(rawyaml))

# modified call to json.load or json.loads to preserve order by instantiating
# Item instances rather than dict
import json
data = json.loads(rawjson, object_pairs_hook=Item)

循环

目前未组织处理循环数据结构。这些数据结构在处理JSON、XML和其他常见数据格式时不会出现,但可能会是一个很好的未来扩展。

安装

安装或升级到最新版本

pip install -U items

有时Python安装的pip名称不同(例如pip、pip2和pip3),在拥有多个Python版本的系统中,pip与哪个Python解释器搭配可能会令人困惑。在这种情况下,尝试将pip作为您要安装的Python版本的模块运行。这可以减少冲突和混淆

python3.6 -m pip install -U items

在Unix、Linux和macOS上,您可能需要在命令前加上sudo以授权安装。在没有超级用户权限的环境中,您可能希望使用pip的--user选项,只为单个用户安装,而不是系统范围的。

测试

如果您想在本地上运行模块测试,则需要安装pytest和tox。要进行完整测试,您还需要pytest-cov和coverage。然后运行以下命令之一

tox                # normal run - speed optimized
tox -e py37        # run for a specific version only
tox -c toxcov.ini  # run full coverage tests

注意

  • 不适用于Python 2。应该适用于Python 3的3.6之前的版本,但不保证。由于3.6之前字典排序规则不同,测试会更困难。由于这是一个面向未来的模块,目前没有精力将其修改为过时的方言。

项目详情


下载文件

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

源分布

items-0.6.5.tar.gz (9.2 kB 查看散列)

上传时间

构建分布

items-0.6.5-py3-none-any.whl (10.8 kB 查看散列)

上传时间 Python 3

由以下机构支持

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