Python中如何根据文件是否压缩选择with语句,避免重复代码?
问题
我需要打开一个可能经过gzip压缩或未压缩的文件,目前分别用以下两种方式调用some_func(f):
with open(myfile, 'r') as f: some_func(f) # 任意函数
或者
import gzip with gzip.open(myfile, 'r') as f: some_func(f)
我会通过布尔变量myfile_gzipped判断文件是否为压缩文件,当前的实现如下:
# myfile_gzipped 是标识文件是否压缩的布尔变量 if myfile_gzipped: with gzip.open(myfile, 'rb') as f: some_func(f) else: with open(myfile, 'r') as f: some_func(f)
请问如何修改才能避免重复编写some_func(f)这段代码?
解决方案
方法1:统一选择文件打开逻辑
先根据myfile_gzipped的值确定要使用的打开函数和模式,再通过同一个with语句执行文件操作,这样some_func(f)只需编写一次:
import gzip open_func = gzip.open if myfile_gzipped else open mode = 'rb' if myfile_gzipped else 'r' with open_func(myfile, mode) as f: some_func(f)
方法2:内联条件判断
可以将条件判断直接嵌入with语句中,一行完成文件对象的选择,避免分支重复:
import gzip with (gzip.open(myfile, 'rb') if myfile_gzipped else open(myfile, 'r')) as f: some_func(f)
方法3:封装为可复用的上下文管理器
如果该逻辑需要多次使用,建议封装成自定义上下文管理器,提升代码复用性,同时自动处理压缩文件的模式适配:
import gzip from contextlib import contextmanager @contextmanager def open_maybe_gzipped(filename, is_gzipped, mode='r'): if is_gzipped: # 自动转换为压缩文件适配的二进制模式 adjusted_mode = mode.replace('t', '') + 'b' if 't' in mode else mode + 'b' with gzip.open(filename, adjusted_mode) as f: yield f else: with open(filename, mode) as f: yield f # 调用示例 with open_maybe_gzipped(myfile, myfile_gzipped) as f: some_func(f)
内容的提问来源于stack exchange,提问作者irene
相关产品推荐
相关产品推荐

