Python每日一练0022

问题

你想在一个文件里每次读入固定大小的字节,比如每次读入4个字节并转成int,或者每次读入x个字节并进行结构化,例如:

l = [5, 2, 4, 1, 2, 4, 5, 6, 8]
with open('test', 'wb') as fd:
    for num in l:
        fd.write(num.to_bytes(4, 'big'))

解决方案

可以简单的用while循环来完成

with open('test', 'rb') as fd:
    r = fd.read(4)
    while r:
        print(int.from_bytes(r, 'big'), end=' ')
        r = fd.read(4)

输出为5 2 4 1 2 4 5 6 8

但更优雅的做法是结合使用iterfunctools.partial

from functools import partial
with open('test', 'rb') as fd:
    for r in iter(partial(fd.read, 4), b''):
        print(int.from_bytes(r, 'big'), end=' ')

输出同样是5 2 4 1 2 4 5 6 8

讨论

functools.partial的作用是对一个函数进行包装(可以将一些参数的值固定)并生成一个新的签名,例如:

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18

functools.partial的大致实现如下:

def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

iter的作用是当只有一个参数时,对这个对象进行迭代,所以这个对象必须实现__iter()____getitem()__方法,例如:

>>> l = [1, 2, 3, 4]
>>> for i in iter(l):
...     print(i, end=' ')
...
>>> 1 2 3 4

但当有两个参数时,第一个参数必须是可调用的(比如函数),第二个参数是终止的值,当调用第一个参数返回的结果等于第二个参数时,迭代就停止了,例如:

with open('mydata.txt') as fp:
    for line in iter(fp.readline, ''):
        process_line(line)

所以综合两个方法来看上面的iter(partial(fd.read, 4), b''),就是每次调用fd.read(4)直到返回一个空的bytes

来源

Python Cookbook

关注

欢迎关注我的微信公众号:python每日一练

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值