From cf67ba87dc1e25a47a130c9e23dab79a5db4b6d8 Mon Sep 17 00:00:00 2001 From: XiongNeng Date: Mon, 22 Sep 2014 18:00:42 +0800 Subject: [PATCH] 5.8 starting... --- cookbook/c05/p08_iterate_fixedsize.py | 20 +++++++++++ .../p08_iterate_over_fixed_sized_records.rst | 35 +++++++++++++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 cookbook/c05/p08_iterate_fixedsize.py diff --git a/cookbook/c05/p08_iterate_fixedsize.py b/cookbook/c05/p08_iterate_fixedsize.py new file mode 100644 index 0000000..21798e6 --- /dev/null +++ b/cookbook/c05/p08_iterate_fixedsize.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +""" +Topic: 固定长度迭代文件 +Desc : +""" +from functools import partial + + +def iterate_fixed(): + RECORD_SIZE = 32 + + with open('somefile.data', 'rb') as f: + records = iter(partial(f.read, RECORD_SIZE), b'') + for r in records: + print(r) + +if __name__ == '__main__': + iterate_fixed() + diff --git a/source/c05/p08_iterate_over_fixed_sized_records.rst b/source/c05/p08_iterate_over_fixed_sized_records.rst index 4de6baa..6dc58f7 100644 --- a/source/c05/p08_iterate_over_fixed_sized_records.rst +++ b/source/c05/p08_iterate_over_fixed_sized_records.rst @@ -5,14 +5,43 @@ ---------- 问题 ---------- -todo... +你想在一个固定长度记录或者数据块的集合上迭代,而不是在一个文件中一行一行的迭代。 + +| ---------- 解决方案 ---------- -todo... +通过下面这个小技巧使用 ``iter`` 和 ``functools.partial()`` 函数: + +.. code-block:: python + + from functools import partial + + RECORD_SIZE = 32 + + with open('somefile.data', 'rb') as f: + records = iter(partial(f.read, RECORD_SIZE), b'') + for r in records: + ... + +这个例子中的 ``records`` 对象是一个可迭代对象,它会不断的产生固定大小的数据块,直到文件末尾。 +要注意的是如果总记录大小不是块大小的整数倍的话,最后一个返回元素的字节数会比期望值少。 + +| ---------- 讨论 ---------- -todo... \ No newline at end of file +A little-known feature of the iter() function is that it can create an iterator if you pass +it a callable and a sentinel value. The resulting iterator simply calls the supplied callable +over and over again until it returns the sentinel, at which point iteration stops. + +In the solution, the functools.partial is used to create a callable that reads a fixed +number of bytes from a file each time it’s called. The sentinel of b'' is what gets returned +when a file is read but the end of file has been reached. + +Last, but not least, the solution shows the file being opened in binary mode. For reading +fixed-sized records, this would probably be the most common case. For text files, reading +line by line (the default iteration behavior) is more common. +