Конце линии конвертер


Недавно я написал Python скрипт для преобразования нескольких файлов Эол из Unix для DOS и наоборот.

Я ищу советы, чтобы улучшить мой код, или если есть лучший способ делать то, что я пропустил.

#!/usr/bin/env python3

import sys

def main():
    command, *filenames = sys.argv[1:]
    valid_commands = ['-d', '-u']
    sys.tracebacklimit = None

    if not command in valid_commands:
        error = """'{command}'
        Provide the following arguments -u|d file [file2] [file3] ...
        flags:
            -u : converts DOS to UNIX
            -d : converts UNIX to DOS
        example command:
            ./eol -u foo.py bar.py""".format(command=command)

        raise ValueError(error)
        sys.exit(1)

    if filenames:
        convert(filenames, command)
    else:
        print("> no files to convert")

def convert(files, command):
    for file in files:
        text = open(file, 'r').read()

        with open(file, 'w') as current:
            if command == '-u':
                format = 'UNIX'
                current.write(text.replace('\r\n', '\n'))
            elif command == '-d':
                format = 'DOS'
                current.write(text.replace('\n', '\r\n'))

        print("> converting file {filename} to {format} ...".format(
              filename=file, format=format))

if __name__ == "__main__":
    main()


1990
6
задан 27 января 2018 в 04:01 Источник Поделиться
Комментарии
2 ответа

Пара небольших замечаний:


  1. sys.exit(1) никогда не будет достигнута, Так что вы можете удалить его. Видимо, вы не хотите показывать, чтобы тот, кто будет использовать ваш скрипт, укажите хотя это не то, что я рекомендую. Приятно знать, почему и как программа дала сбой (и даже если вы не хотите изменения, вы всегда можете создать свой собственный класс исключений):

    class MyCustomException(Exception):
    pass

    Который можно назвать как:

    if bla_bla:
    raise MyCustomException('my message here')

  2. format = 'UNIX' и format = 'DOS': они, кажется, не используется нигде в коде, так что вы можете удалить их.

  3. Изменение if not command in valid_commands: для if command not in valid_commands:

  4. Использовать две пустые строки между вашими функциями

  5. Использовать argparse модуль для обработки аргументов командной строки

  6. Это: text = open(file, 'r').read() будет загружать весь файл в память, что может быть плохо, если вы претендуете свои функции на очень большой файл. Я рекомендую вам обрабатывать по одной строке за раз, или по крайней мере позвонить f.read(size). Из документов:


    Для чтения файла содержимое, звоните f.read(size), который читает некоторые
    количество данных и возвращает его в виде строки (в текстовом режиме) или байт
    объект (в двоичном режиме). size это необязательный числовой аргумент. Когда
    size опущен или отрицательный, все содержимое файла будет
    прочитал и вернулся; это ваши проблемы если файл в два раза больше
    память вашей машины. В противном случае, в большинстве размер байты не читаются и
    вернулся.

2
ответ дан 27 января 2018 в 05:01 Источник Поделиться

Код в посте не работает, потому что файлы открываются в текстовом режиме, а в текстовом режиме на Python 3 переводит строку по умолчанию. Цитировать документации Python:


строки определяет, как символы конца строки обрабатываются. Это может быть None, '', '\n', '\r'и '\r\n'. Он работает следующим образом:


  • При чтении входных данных из потока, если строки это Noneуниверсальный строки режим включен. Строк во входных данных могут закончиться '\n', '\r'или '\r\n'и эти переведены на '\n' прежде чем возвращается к вызывающей стороне. Если это ''универсальный строки режим включен, но символы перевода строки возвращено непереведенные. Если есть какие-либо другие правовые ценности, входные линии только прекращается по заданной строки и конца строки возвращается непереведенных абонентов.

  • При написании вывода в поток, если строки это Noneлюбой '\n' символы переводятся в систему по умолчанию разделительную линию, os.linesep. Если строки есть '' или '\n'перевод происходит. Если строки любых других правовых ценностей, либо '\n' символы, написанные переводятся в данную строку.


Это означает, что код в пост никогда не получает, чтобы увидеть оригинальную линию окончаний и поэтому он ведет себя не так, как предполагалось при запуске на Windows. (Это заставляет меня подозревать, что он не был протестирован во всех четырех конфигураций: в Unix → ДОС на Unix; Дос → с Unix на Unix; Unix и → DOS на Windows; Дос → Unix на Windows.)

Для того, чтобы работать на исходной линии концовок, вы можете открыть файл в бинарном режиме (как для чтения и записи), или открыть его в текстовом режиме, но установить newline='' так что строки не переводятся.

3
ответ дан 28 января 2018 в 10:01 Источник Поделиться