запуск сценария python3 в командной строке - PullRequest
0 голосов
/ 10 июня 2019

Я написал в Python функцию, которая принимает 2 lists (с такой же длиной) и возвращает другой список с 2 элементами.функция работает отлично, но я пытаюсь запустить скрипт Python в command line.Для этого я хочу использовать модуль argparse в Python.Я написал следующий скрипт на python3, используя следующую команду:

python3 text.py a b results

скрипт должен принимать 3 аргумента, 2 списка в качестве входных данных и один список в качестве выходных.Вот сценарий:

def fun(a, b):
    a_is_greater = 0
    b_is_greater = 0
    for element_a, element_b in zip(a, b):
        if element_a > element_b:
            a_is_greater += 1
        elif element_a < element_b:
            b_is_greater += 1
    return [a_is_greater, b_is_greater]


def main():
    import argparse
    ap = argparse.ArgumentParser(description="")
    ap.add_argument('--list-type', type=list)
    ap.add_argument('--list-type', type=list)
    ap.add_argument('-o', '--outlist', required=True)

    args = ap.parse_args()

    results = fun(a, b)
    return results

if __name__ == "__main__":
    from signal import signal, SIGPIPE, SIG_DFL
    signal(SIGPIPE, SIG_DFL)

    try:
        main()
    except IOError as e:
        if e.errno != 32:
            raise
    except KeyboardInterrupt as e:
        pass

Вы знаете, как это исправить?Я пробовал эти 2 списка: a = [4, 5, 2] и b = [3, 5, 4].Функция fun в скрипте отлично работает для этих 2 входов.

Ответы [ 2 ]

1 голос
/ 10 июня 2019

Это лучше?

python3 text.py --list1 [4,5,2] --list2 [3,5,4] -o result # [1, 1]

def main():
    import argparse

    ap = argparse.ArgumentParser(description="")
    ap.add_argument('--list1', type=list)
    ap.add_argument('--list2', type=list)
    ap.add_argument('-o', '--outlist', required=True)
    args = ap.parse_args()

    results = fun(args.list1, args.list2)
    print(results)
    return results

Код:

def fun(a, b):
    a_is_greater = 0
    b_is_greater = 0
    for element_a, element_b in zip(a, b):
        if element_a > element_b:
            a_is_greater += 1
        elif element_a < element_b:
            b_is_greater += 1
    return [a_is_greater, b_is_greater]


def main():
    import argparse

    ap = argparse.ArgumentParser(description="")
    ap.add_argument('--list1', type=list)
    ap.add_argument('--list2', type=list)
    ap.add_argument('-o', '--outlist', required=True)
    args = ap.parse_args()

    results = fun(args.list1, args.list2)
    print(results)
    return results

if __name__ == "__main__":
    from signal import signal, SIGPIPE, SIG_DFL
    signal(SIGPIPE, SIG_DFL)

    try:
        main()
    except IOError as e:
        if e.errno != 32:
            raise
    except KeyboardInterrupt as e:
        pass
0 голосов
/ 11 июня 2019

С исправленным кодом с использованием type=list, sys.argv и args отображается как:

1353:~/mypy$ python3 stack56531390.py --list1 [4,5,2] --list2 [3,5,4] -o result
['stack56531390.py', '--list1', '[4,5,2]', '--list2', '[3,5,4]', '-o', 'result']
Namespace(list1=['[', '4', ',', '5', ',', '2', ']'], list2=['[', '3', ',', '5', ',', '4', ']'], outlist='result')
[1, 1]

Обратите внимание, что списки входят как строки. Функция list разбивает эту строку на список символов.

In [607]: list('astring')                                                                              
Out[607]: ['a', 's', 't', 'r', 'i', 'n', 'g']

Тот факт, что fun работает для этих входов, скорее совпадение, а не дизайн. Входы не соответствуют проверенным: a = [4, 5, 2]' and 'b = [3, 5, 4].

Посмотрите, что произойдет, если пользователь поместит пробелы в списках:

1355:~/mypy$ python3 stack56531390.py --list1 [4, 5, 2] --list2 [3,5,4] -o result
usage: stack56531390.py [-h] [--list1 LIST1] [--list2 LIST2] -o OUTLIST
stack56531390.py: error: unrecognized arguments: 5, 2]

или кавычки, чтобы сохранить разделенные списки вместе:

1357:~/mypy$ python3 stack56531390.py --list1 "[4, 5, 2]" --list2 [3,5,4] -o result
['stack56531390.py', '--list1', '[4, 5, 2]', '--list2', '[3,5,4]', '-o', 'result']
Namespace(list1=['[', '4', ',', ' ', '5', ',', ' ', '2', ']'], list2=['[', '3', ',', '5', ',', '4', ']'], outlist='result')
[2, 3]

Так что, хотя type=list можно заставить работать, обычно это не лучший выбор. Помните, argparse type - это функция, которой присваивается строка; это не спецификатор типа или класса.

Если я изменю два аргумента на * входные данные типа int:

ap.add_argument('--list1', nargs='*', type=int)
ap.add_argument('--list2', nargs='*', type=int)

1358:~/mypy$ python3 stack56531390.py --list1 4 5 2  --list2 3 5 4 -o result
['stack56531390.py', '--list1', '4', '5', '2', '--list2', '3', '5', '4', '-o', 'result']
Namespace(list1=[4, 5, 2], list2=[3, 5, 4], outlist='result')
[1, 1]

Теперь двумя входными данными являются обычные списки целых чисел, а не те списки символов, которые включают скобки и запятые. Сравнение будет числовым, а не лексическим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...