Python 根据文件扩展名打开语句
我需要在一个目录中处理两种类型的文件-Python 根据文件扩展名打开语句,python,python-3.x,Python,Python 3.x,我需要在一个目录中处理两种类型的文件-.txt和.gz。 为此,有两种类型的公开声明: .gz文件: with gzip.open(file_name, 'rt', encoding='utf-8') as f: line = next(f) while line: some code with open(file_name, 'r', encoding='utf-8') as f: line = next(f) while line:
.txt
和.gz
。
为此,有两种类型的公开声明:
.gz文件:
with gzip.open(file_name, 'rt', encoding='utf-8') as f:
line = next(f)
while line:
some code
with open(file_name, 'r', encoding='utf-8') as f:
line = next(f)
while line:
some code
.txt文件:
with gzip.open(file_name, 'rt', encoding='utf-8') as f:
line = next(f)
while line:
some code
with open(file_name, 'r', encoding='utf-8') as f:
line = next(f)
while line:
some code
任何进一步的处理命令都是完全相同的。现在我看到了处理这两种文件类型的两个选项:
选项1-使用两个相同的函数,它们的不同之处仅在于open
语句。听起来很难看
选项2-如果构造如下,则使用:
if ext == '.gz':
f = gzip.open(file_name, 'rt', encoding='utf-8')
elif ext == '.txt':
f = open(file_name, 'r', encoding='utf-8')
line = next(f)
while line:
some code
但在我看来还是很尴尬:/
问题:Python 3.x中根据文件扩展名使用open语句的Python方式是什么?为什么不:
with (gzip.open if ext==".gz" else open)(file_name, 'rt', encoding='utf-8') as f:
with
的第一个参数是三元表达式,根据扩展名决定使用哪个函数。我在这两种情况下都使用了'rt'
,这是标准打开的默认设置。该方法的优点是避免了复制/粘贴,并且能够使用上下文管理器
也许可以使用辅助函数创建一些泛型函数:
def myopen(file_name)
return (gzip.open if os.path.splitext(file_name)[1]==".gz" else open)(file_name, 'rt', encoding='utf-8')
使用类似于:
with myopen(file_name):
我想提出以下建议:
#------------------------------------
import zipfile
#-----------------------Common Code-------------------------
def disp_line(filee):
for line in filee.readlines():
print(line)
#-----------------------First File-----------------------
z = zipfile.ZipFile('D:\\DC-Data\\baby_names.zip', "r")
zinfo = z.namelist()
for name in zinfo:
with z.open(name) as filee:
disp_line(filee)
#-----------------------2nd File-------------------------
with open('D:\\DC-Data\\iris.txt', 'r') as filee:
disp_line(filee)
#------------------------End ----------------------
另一种方法是使用扩展名为键的defaultdict
from collections import defaultdict
from pathlib import Path
open_functions = defaultdict(lambda: (open, ("r",), {encoding: "utf-8"}))
open_functions["gz"] = (gzip.open, ("rt",), {encoding: "utf-8"})
filename = Path(filename)
open_function, args, kwargs = open_functions[filename.suffix]
with open_function(filename, *args, **kwargs) as f:
...
哇!看起来不错!:)非常感谢,@Jean François!明天早上测试,如果有效,接受你的答案。在经历了不眠之夜的周末之后,我已经太累了。。。干杯。为什么在这里使用lambda
而不是def
?<>代码lambda < /COD>的全部要点是,您不必提供名称,并且可以将其嵌入到表达式的中间。但是你把它放在它自己的语句中,并给它一个名称(但这个名称不会反映在堆栈跟踪中,例如堆栈跟踪),那么为什么呢?是的,不需要lambda。这是一个单行函数,但不是必需的。那是。。。相当多。如果ext='.gz':f=gzip.open(文件名,…)
等,只需使用,然后用f:
使用。没有什么规定您必须在with
语句中创建上下文管理器。您知道,如果我在现实世界中看到这样的代码(不是这样),我会认为它是由一位新手编写的,他发现其中一行代码令人印象深刻。我们可以编写不需要水平滚动条的代码吗?