Я пытаюсь выяснить, какой лучший способ открытия файла Python основан на его типе.

Например, у меня есть что-то базовое, подобное этому, но оно просто не кажется мне «питоническим», и я чувствую, что каким-то образом это можно реорганизовать и написать более чётко;

def openfile(filename):
    if read_file_from_top:
        if not filename.endswith('.gz'):
            with open(filename, 'r') as infile:
                for line in infile:
                   # do something
        else:
            with gzip.open(filename, 'r') as infile:
                for line in infile:
                   # do something
    elif read_file_from_bottom:
        if not filename.endswith('.gz'):
            with open(filename, 'r') as infile:
                for line in infile:
                    # do something
        else:
            with gzip.open(filename, 'r') as infile:
                for line in infile:
                    # do something

Будет ли лучший способ сделать это, возможно, с помощью генератора? Благодарю.

3
user1165419 7 Янв 2017 в 22:42

3 ответа

Лучший ответ

Вы должны разделить открытие и чтение:

def openfile(filename, mode='r'):
    if filename.endswith('.gz'):
        return gzip.open(filename, mode) 
    else:
        return open(filename, mode)

with openfile(filename, 'r') as infile:
    for line in infile:
       # do something
6
Mr. T 15 Мар 2018 в 07:17

Краткое решение с использованием предварительно определенного списка важных функций:

def processFile(filepath):
    with [open, gzip.open][0 if not filepath.endswith('.gz') else 1](filepath, 'r') as fh:
        if read_file_from_top:
            # do something
        elif read_file_from_bottom:
            # do something
0
RomanPerekhrest 7 Янв 2017 в 20:21

Я думаю, что-то вроде этого, по крайней мере, немного лучше:

import gzip


def file_line_gen(filename):
    if filename.endswith('.gz'):
        open_fn = gzip.open
    else:
        open_fn = open

    with open_fn(filename, 'r') as f:
        for line in f:
            yield line


for line in file_line_gen('data.gz'):
    # do something here
    print repr(line)
2
John Szakmeister 7 Янв 2017 в 19:52