解析带有头部和尾部的输入流。
项目描述
概述
header_detail_footer模块提供了一种解析包含标题行、未知数量的数据行(称为详情)和尾部的输入可迭代对象(通常是文本文件)的方法。解析开始时必须指定标题和尾部行的数量。可以有零个或多个标题行,以及独立地零个或多个尾部行。详情行是标题和尾部之间的所有行。如果一个文件只包含标题和尾部,则不会有详情行。
模块API由一个函数parse()和几个异常组成。
请注意,每个输入“行”的内容从未被检查:它们只是被迭代并由解析器返回。它们通常是字符串,但它们可以是任何对象。
典型用法
此代码展示了parse()函数的简单用法
>>> from header_detail_footer import parse >>> header, details, footer = parse(['header', 'row 1', 'row 2', 'footer']) >>> header 'header' >>> list(details) ['row 1', 'row 2'] >>> footer() 'footer'
parse()函数
parse()函数接受1个必需参数,即输入可迭代对象。有两个可选参数,header_rows和footer_rows。两者默认为1。它们分别代表输入中存在的标题和尾部行的数量。
parse()返回一个3元组:(header, details, footer)。header是如果有任何标题行,则是标题行;details是返回每个详情行的迭代器;footer是如果有任何尾部行,则返回一个可调用的尾部行。
对于header和footer(),如果header_rows或footer_rows为1,则分别返回输入中的一个行。否则,包括0行的情况,它们包含一个列表
>>> header, details, footer = parse(['row 1', 'row 2', 'footer 1', 'footer 2'], ... header_rows=0, footer_rows=2) >>> header [] >>> list(details) ['row 1', 'row 2'] >>> footer() ['footer 1', 'footer 2']
返回的尾部可调用函数永远不会被调用。如果调用footer,则必须已耗尽details,否则会引发RuntimeError
>>> header, detail, footer = parse('abc') >>> footer() Traceback (most recent call last): ... RuntimeError: called footer() before details were exhausted
异常
在模块级别定义了两个异常:HeaderError 和 FooterError。请注意,这些异常是在 parser() 方法中抛出的。在迭代标题、详细内容或页脚时,它们永远不会被抛出。
HeaderError
当输入不包含足够的行用于标题时,由 parser() 抛出。
>>> header, details, footer = parse(['row 1'], header_rows=3) #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... HeaderError: too few rows for header
与 CSV 文件的使用
如果您有一个包含列名的标题行的 CSV 文件,并且还有一个页脚行,那么告诉 header_detail_footer 没有标题行是最简单的。这样,细节迭代器就可以传递给 csv.DictReader,它将像往常一样获取标题行。
>>> import csv # here, the footer row contains a row count >>> _, details, footer = parse(['FRUIT,COLOR', ... 'apple,red', ... 'orange,orange', ... 'rowcount:2'], ... header_rows=0) # specify 0 header rows # pass the details to csv.DictReader. this includes what is now # the csv header row >>> reader = csv.DictReader(details) # print out each row >>> for count, row in enumerate(reader, 1): ... (count, [(key, value) for key, value in sorted(row.items())]) ... (1, [('COLOR', 'red'), ('FRUIT', 'apple')]) (2, [('COLOR', 'orange'), ('FRUIT', 'orange')]) # verify the footer count >>> _, _, footer_count = footer().partition(':') >>> int(footer_count) == count True
变更日志
2.4 2016-10-27 Eric V. Smith
将分发名称重命名为用下划线替换连字符。名称现在是 header_detail_footer(问题 #7)。
移除重命名 RPM 的黑客技巧(问题 #5)。
始终需要 setuptools(问题 #4)。
没有代码更改。
2.3 2014-03-13 Eric V. Smith
将 MANIFEST.in 添加到 MANIFEST.in(问题 #2)。
让 bdist_rpm 使用包名 'python-header-detail-footer'(问题 #3)。
2.2 2013-12-03 Eric V. Smith
添加有关 CSV 文件的文档。
将协议错误从 ValueError 更改为 RuntimeError。关闭 Bitbucket 问题 #1。
2.1 2013-11-16 Eric V. Smith
添加 MANIFEST.in,以便非代码文件最终位于 sdist 中。
2.0 2013-11-15 Eric V. Smith
更改了 API,现在只为页脚返回可调用对象,因为这是在详细内容耗尽后需要延迟的唯一内容。
更改了命名法:现在使用“行”而不是“行”。
1.0 2013-11-15 Eric V. Smith
第一个稳定版本。
0.1 2013-11-14 Eric V. Smith
初始发布。