Валидатор подпроцесса CSV и мультипроцессорной обработки на Python


Этот скрипт Python занимает каталог файлов CSV и вызывает сценарий скала, которая проверяет, является ли содержимое файла соответствует заданному регулярному выражению. Ссылку на этот скрипт Скала можно найти на 3-й линии.

Этот скрипт принимает файл в качестве аргумента, поэтому я создание этого скрипта Python, чтобы накормить его целая стоит каталог файлов, а также с использованием максимально возможного количества ресурсов процессора.

Видите ли вы какие-либо вопросы или потенциальные улучшения в моем коде?

"""
Command line API to CSV validator using Scala implementation from:
http://digital-preservation.github.io/csv-validator/#toc7
"""

PATH_TO_VALIDATOR = r"C:\prog\csv\csv-validator-cmd-1.2-RC2\bin\validate.bat"
PATH_TO_CSV_FOLDER = r"C:\prog\csv\CSVFiles"
PATH_TO_CSV_SCHEMA = r"C:\prog\csv\ocr-schema.csvs"

# Set defaults
CSV_ENCODING = "windows-1252"
CSV_SCHEMA_ENCODING = "UTF-8"


def open_csv(CSV_LIST):
    import subprocess

    # To be used to display a simple progress indicator
    TOTAL_FILE_COUNT = len(CSV_LIST)
    current_file_count = 1

    with open("output.txt", 'w') as output:
        for filename in CSV_LIST:
            print("Processing file " + str(current_file_count) + "/" + str(TOTAL_FILE_COUNT))

            output.write(filename + ': ')
            validator = subprocess.Popen(
                [PATH_TO_VALIDATOR, PATH_TO_CSV_FOLDER + "/" + filename, PATH_TO_CSV_SCHEMA, "--csv-encoding",
                 CSV_ENCODING, "--csv-schema-encoding", CSV_SCHEMA_ENCODING, '--fail-fast', 'true'], stdout=subprocess.PIPE)
            result = validator.stdout.read()
            output.write(result.decode('windows-1252'))

            current_file_count += 1


# Split a list into n sublists of roughly equal size
def split_list(alist, wanted_parts=1):
    length = len(alist)
    return [alist[i * length // wanted_parts: (i + 1) * length // wanted_parts]
            for i in range(wanted_parts)]


if __name__ == '__main__':
    import argparse
    import multiprocessing
    import os

    parser = argparse.ArgumentParser(description="Command line API to Scala CSV validator")
    parser.add_argument('-pv', '--PATH_TO_VALIDATOR', help="Specify the path to csv-validator-cmd/bin/validator.bat",
                        required=True)
    parser.add_argument('-pf', '--PATH_TO_CSV_FOLDER', help="Specify the path to the folder containing the csv files "
                                                            "you want to validate", required=True)
    parser.add_argument('-ps', '--PATH_TO_CSV_SCHEMA', help="Specify the path to CSV schema you want to use to "
                                                            "validate the given files", required=True)

    parser.add_argument('-cenc', '--CSV_ENCODING', help="Optional parameter to specify the encoding used by the CSV "
                                                        "files. Choose UTF-8 or windows-1252. Default windows-1252")
    parser.add_argument('-csenc', '--CSV_SCHEMA_ENCODING', help="Optional parameter to specify the encoding used by "
                                                                "the CSV Schema. Choose UTF-8 or windows-1252. "
                                                                "Default UTF-8")

    args = vars(parser.parse_args())

    if args['CSV_ENCODING'] is not None:
        CSV_ENCODING = args['CSV_ENCODING']

    if args['CSV_SCHEMA_ENCODING'] is not None:
        CSV_SCHEMA_ENCODING = args['CSV_SCHEMA_ENCODING']

    PATH_TO_VALIDATOR = args["PATH_TO_VALIDATOR"]
    PATH_TO_CSV_SCHEMA = args["PATH_TO_CSV_SCHEMA"]
    PATH_TO_CSV_FOLDER = args["PATH_TO_CSV_FOLDER"]

    CPU_COUNT = multiprocessing.cpu_count()

    split_csv_directory = split_list(os.listdir(args["PATH_TO_CSV_FOLDER"]), wanted_parts=CPU_COUNT)

    # Spawn a Process for each CPU on the system
    for csv_list in split_csv_directory:
        p = multiprocessing.Process(target=open_csv, args=(csv_list,))
        p.start()


Комментарии
1 ответ

Только несколько небольших вещей, которые я хотел бы предложить изменения.

Pep8

Вы должны рассмотреть возможность форматирования кода в соответствии с pep8. Это важно при обмене код, как единый стиль делает его гораздо легче для других программистов, которые будут читать ваш код. Существуют различные инструменты, доступные, чтобы помочь сделать код совместимым pep8. Я использую PyCharm IDE, которая покажет pep8 нарушения прямо в Редакторе.

ALL_CAPS_IS_FOR_CONSTS

Так что написано заглавными_буквами, как правило, зарезервированы для постоянных величин. Так что такого рода вещи:

TOTAL_FILE_COUNT = len(CSV_LIST)

это более подходящие для Python, как:

total_file_count = len(CSV_LIST)

А еще лучше избавиться от это промежуточное задание в целом с:

print("Processing file {}/{}".format(current_file_count, len(CSV_LIST)))

Тестирование на присутствие в словарь

Часто, когда вы найдете код проверки для ключа присутствие в дикт перед выполнением некоторых работ:

if args['CSV_ENCODING'] is not None:
CSV_ENCODING = args['CSV_ENCODING']

В принципе то же самое может быть сделано без явной проверки:

CSV_ENCODING = args.get('CSV_ENCODING', CSV_ENCODING)

1
ответ дан 29 января 2018 в 06:01 Источник Поделиться