前面的问题:
标准库中是否有一种 Pythonic 方法可以使用for ... in ...
语法(即/ )解析原始二进制文件,该语法(即__iter__
/ __next__
)产生尊重buffersize
参数的块,而无需子类IOBase
或其子类?
详细解释
我想打开一个原始文件进行解析,利用for ... in ...
语法,我希望该语法能够产生可预测的形状对象。对于我正在处理的问题,这并没有按预期发生,因此我尝试了以下测试(import numpy as np
必需):
In [271]: with open('tinytest.dat', 'wb') as f:
...: f.write(np.random.randint(0, 256, 16384, dtype=np.uint8).tobytes())
...:
In [272]: np.array([len(b) for b in open('tinytest.dat', 'rb', 16)])
Out[272]:
array([ 13, 138, 196, 263, 719, 98, 476, 3, 266, 63, 51,
241, 472, 75, 120, 137, 14, 342, 148, 399, 366, 360,
41, 9, 141, 282, 7, 159, 341, 355, 470, 427, 214,
42, 1095, 84, 284, 366, 117, 187, 188, 54, 611, 246,
743, 194, 11, 38, 196, 1368, 4, 21, 442, 169, 22,
207, 226, 227, 193, 677, 174, 110, 273, 52, 357])
我不明白为什么会出现这种随机行为,为什么不尊重这个buffersize
论点。使用read1
给出了预期的字节数:
In [273]: with open('tinytest.dat', 'rb', 16) as f:
...: b = f.read1()
...: print(len(b))
...: print(b)
...:
16
b'M\xfb\xea\xc0X\xd4U%3\xad\xc9u\n\x0f8}'
它就是:第一个块末尾附近的换行符。
In [274]: with open('tinytest.dat', 'rb', 2048) as f:
...: print(f.readline())
...:
b'M\xfb\xea\xc0X\xd4U%3\xad\xc9u\n'
果然,readline
被调用以生成文件的每个块,并且它在换行值(对应于 10)上跳闸。我通过代码验证了这个阅读,IOBase 定义中的行:
571 def __next__(self):
572 line = self.readline()
573 if not line:
574 raise StopIteration
575 return line
所以我的问题是这样的:是否有一些更 Pythonic 的方式来实现buffersize
- 尊重原始文件行为,允许for ... in ...
语法,而不必子类IOBase
或其子类(因此,不是标准库的一部分)?如果不是,这种意外行为是否需要 PEP?(或者它是否值得学习去期待这种行为?:)