2015-10-27 96 views
2

在Python 2.7中,我想打開一個文件並對其進行一些操作。問題是我不知道它是否有.csv.csv.gz擴展名。如果我知道這是.csv,我會做統一打開.csv和.csv.gz文件

with open(filename, "r") as f_in: 
    do something 

如果我知道這是.csv.gz,我可以說

import gzip 

with gzip.open(filename, "r") as f_in: 
    do something 

我很好奇,如果有是爲了避免搞清楚該文件後,重複的方式延伸:

def find_ext(filename): 
    return filename.split(".")[-1] 

ext = find_ext(filename) 

if ext == "csv": 
    with open(filename, "r") as f_in: 
     do something 
else if ext == "gz": 
    import gzip 
    with gzip.open(filename, "r") as f_in: 
     do something 

回答

0
import gzip 
import mimetypes 

smart_open = lambda fn: {"gzip": gzip.open(fn)}.get(mimetypes.guess_type(fn)[1], open(fn)) 

# usage: 
f = smart_open("test.csv.gz") 
f = smart_open("test.csv") 
1

我就懶得看文件擴展名的文件重新命名或使用非標準變體。

而是打開原始文件並檢查標題。如果它以兩個32-bit單詞0x00088b1f0開頭,則它是一個gzip文件。

import struct 

f = open(filename, 'rb') 
v = f.read(8) 
v1 = struct.unpack('I', v)[0] 
v2 = struct.unpack('I', v)[1] 
if v1 == 0x00088b1f and v2 == 0: 
    # it is gzip 
0

由於在不同情況下使用不同的庫,所以需要檢查擴展名。

try: 
    ... 
except AnError: 
    ... 
else: 
    ... 
finally: 
    ... 

無論如何,一個(的if/else)或其他(嘗試/最後)建設的類型是必要的,因爲文件打開過程不是不同情況相同。但一個可以與建造,比如去。

爲了避免重複使用這樣的方法(它是僞代碼):

def readcsv(file): 
    ... 

def readgzip(file): 
    ... 

if csv: 
    readcsv(file) 
elif gzip: 
    readgzip(file)