[python] argparse를 사용하여 목록을 명령 행 인수로 전달하려면 어떻게해야합니까?

명령 줄 프로그램에 인수로 목록을 전달하려고합니다. 거기에 argparse옵션으로 목록을 전달하는 옵션은?

parser.add_argument('-l', '--list',
                      type=list, action='store',
                      dest='list',
                      help='<Required> Set flag',
                      required=True)

스크립트는 아래와 같이 불립니다

python test.py -l "265340 268738 270774 270817"



답변

TL; DR

사용자 인터페이스의 작동 방식에 따라 nargs옵션 또는 옵션 'append'설정을 사용하십시오 action.

나르 그

parser.add_argument('-l','--list', nargs='+', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 2345 3456 4567

nargs='+'하나 이상의 인수를 nargs='*'취하고 0 이상을 취합니다.

덧붙이다

parser.add_argument('-l','--list', action='append', help='<Required> Set flag', required=True)
# Use like:
# python arg.py -l 1234 -l 2345 -l 3456 -l 4567

함께 append하면 목록을 구축 할 수있는 옵션이 여러 번 제공합니다.

사용하지 마십시오 type=list! type=list함께 사용하고 싶은 상황은 없을 것 입니다 argparse. 이제까지.


이를 위해 시도 할 수있는 여러 가지 방법과 최종 결과에 대해 자세히 살펴 보겠습니다.

import argparse

parser = argparse.ArgumentParser()

# By default it will fail with multiple arguments.
parser.add_argument('--default')

# Telling the type to be a list will also fail for multiple arguments,
# but give incorrect results for a single argument.
parser.add_argument('--list-type', type=list)

# This will allow you to provide multiple arguments, but you will get
# a list of lists which is not desired.
parser.add_argument('--list-type-nargs', type=list, nargs='+')

# This is the correct way to handle accepting multiple arguments.
# '+' == 1 or more.
# '*' == 0 or more.
# '?' == 0 or 1.
# An int is an explicit number of arguments to accept.
parser.add_argument('--nargs', nargs='+')

# To make the input integers
parser.add_argument('--nargs-int-type', nargs='+', type=int)

# An alternate way to accept multiple inputs, but you must
# provide the flag once per input. Of course, you can use
# type=int here if you want.
parser.add_argument('--append-action', action='append')

# To show the results of the given option to screen.
for _, value in parser.parse_args()._get_kwargs():
    if value is not None:
        print(value)

기대할 수있는 결과는 다음과 같습니다.

$ python arg.py --default 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567

$ python arg.py --list-type 1234 2345 3456 4567
...
arg.py: error: unrecognized arguments: 2345 3456 4567

$ # Quotes won't help here... 
$ python arg.py --list-type "1234 2345 3456 4567"
['1', '2', '3', '4', ' ', '2', '3', '4', '5', ' ', '3', '4', '5', '6', ' ', '4', '5', '6', '7']

$ python arg.py --list-type-nargs 1234 2345 3456 4567
[['1', '2', '3', '4'], ['2', '3', '4', '5'], ['3', '4', '5', '6'], ['4', '5', '6', '7']]

$ python arg.py --nargs 1234 2345 3456 4567
['1234', '2345', '3456', '4567']

$ python arg.py --nargs-int-type 1234 2345 3456 4567
[1234, 2345, 3456, 4567]

$ # Negative numbers are handled perfectly fine out of the box.
$ python arg.py --nargs-int-type -1234 2345 -3456 4567
[-1234, 2345, -3456, 4567]

$ python arg.py --append-action 1234 --append-action 2345 --append-action 3456 --append-action 4567
['1234', '2345', '3456', '4567']

테이크 아웃 :

  • 사용 nargs또는action='append'
    • nargs사용자 관점에서 더 간단 할 수 있지만 위치 인수 argparse가 있어야하는 위치와 위치 인수가 무엇인지 알 수 없기 때문에 위치 인수가 있으면 직관적이지 않을 수 있습니다 nargs. 위치 인수가 있으면 action='append'더 나은 선택이 될 수 있습니다.
    • 경우 위의 사실이 아니라 nargs주어진 '*', '+'또는 '?'. 정수 숫자 (예 :)를 제공하면 옵션에 대해 예상되는 값의 수를 정확히 알 수 4있으므로 옵션 nargs과 위치 인수를 혼합하는 데 문제가 없습니다 argparse.
  • 명령 행에 따옴표를 사용하지 마십시오 1
  • type=list목록의 목록을 반환하므로를

    사용하지 마십시오

    • 이것은 후드 아래에서 모든 인수의 집계가 아니라 선택한 개별 인수에 대해 개별 인수 를 강제하기 위해 argparse의 값을 사용 하기 때문 입니다.typetype
    • type=intint (또는 무엇이든) 목록을 얻기 위해 (또는 무엇이든) 사용할 수 있습니다

1 : 나는 일반적으로 의미하지 않습니다 .. 목록을 전달하기argparse 위해 따옴표를 사용 하는 것은 당신이 원하는 것이 아닙니다.


답변

스크립트에서 나중에 구문 분석하는 구분 된 문자열을 전달하는 것을 선호합니다. 그 이유는 다음과 같습니다. 목록은 모든 유형의 수 있습니다 int또는 str, 때로는 사용하여 nargs여러 선택적 인수 및 위치 인수가있는 경우 문제가 I 실행.

parser = ArgumentParser()
parser.add_argument('-l', '--list', help='delimited list input', type=str)
args = parser.parse_args()
my_list = [int(item) for item in args.list.split(',')]

그때,

python test.py -l "265340,268738,270774,270817" [other arguments]

또는,

python test.py -l 265340,268738,270774,270817 [other arguments]

잘 작동합니다. 구분 기호도 공백이 될 수 있지만 질문의 예와 같이 인수 값 주위에 인용 부호를 적용합니다.


답변

또한 목록을 미리 알고 있으면 nargs사용할 수도 있습니다 choices.

>>> parser = argparse.ArgumentParser(prog='game.py')
>>> parser.add_argument('move', choices=['rock', 'paper', 'scissors'])
>>> parser.parse_args(['rock'])
Namespace(move='rock')
>>> parser.parse_args(['fire'])
usage: game.py [-h] {rock,paper,scissors}
game.py: error: argument move: invalid choice: 'fire' (choose from 'rock',
'paper', 'scissors')


답변

argparse의 add_argument 메소드에서 nargs 매개 변수 사용

nargs = ‘ ‘를 add_argument 매개 변수로 사용합니다. 명시 적 인수를 전달하지 않으면 기본값을 선택하는 옵션에 nargs = ‘ ‘를 사용했습니다.

예제로 코드 스 니펫 포함 :

예 : temp_args1.py

참고 : 아래 샘플 코드는 python3으로 작성되었습니다. print 문 형식을 변경하면 python2에서 실행할 수 있습니다

#!/usr/local/bin/python3.6

from argparse import ArgumentParser

description = 'testing for passing multiple arguments and to get list of args'
parser = ArgumentParser(description=description)
parser.add_argument('-i', '--item', action='store', dest='alist',
                    type=str, nargs='*', default=['item1', 'item2', 'item3'],
                    help="Examples: -i item1 item2, -i item3")
opts = parser.parse_args()

print("List of items: {}".format(opts.alist))

참고 : 목록에 저장된 여러 문자열 인수를 수집하고 있습니다-opts.alist 정수 목록을 원하면 parser.add_argument의 type 매개 변수를 int로 변경하십시오.

실행 결과 :

python3.6 temp_agrs1.py -i item5 item6 item7
List of items: ['item5', 'item6', 'item7']

python3.6 temp_agrs1.py -i item10
List of items: ['item10']

python3.6 temp_agrs1.py
List of items: ['item1', 'item2', 'item3']


답변

단일 스위치가 여러 매개 변수를 사용하도록하려면을 사용 nargs='+'합니다. 예제 ‘-l’이 실제로 정수를 사용하는 경우 :

a = argparse.ArgumentParser()
a.add_argument(
    '-l', '--list',  # either of this switches
    nargs='+',       # one or more parameters to this switch
    type=int,        # /parameters/ are ints
    dest='list',     # store in 'list'.
    default=[],      # since we're not specifying required.
)

print a.parse_args("-l 123 234 345 456".split(' '))
print a.parse_args("-l 123 -l=234 -l345 --list 456".split(' '))

생산

Namespace(list=[123, 234, 345, 456])
Namespace(list=[456])  # Attention!

동일한 인수를 여러 번 지정하면 기본 작업 ( 'store')이 기존 데이터를 대체합니다.

대안은 append조치 를 사용하는 것입니다 .

a = argparse.ArgumentParser()
a.add_argument(
    '-l', '--list',  # either of this switches
    type=int,        # /parameters/ are ints
    dest='list',     # store in 'list'.
    default=[],      # since we're not specifying required.
    action='append', # add to the list instead of replacing it
)

print a.parse_args("-l 123 -l=234 -l345 --list 456".split(' '))

어느 생산

Namespace(list=[123, 234, 345, 456])

또는 쉼표로 구분 된 값을 구문 분석하기 위해 사용자 정의 핸들러 / 액션을 작성할 수 있습니다.

-l 123,234,345 -l 456


답변

에서는 add_argument(), type단지 문자열 반환 옵션 값을받는 호출 객체입니다.

import ast

def arg_as_list(s):
    v = ast.literal_eval(s)
    if type(v) is not list:
        raise argparse.ArgumentTypeError("Argument \"%s\" is not a list" % (s))
    return v


def foo():
    parser.add_argument("--list", type=arg_as_list, default=[],
                        help="List of values")

이를 통해 다음을 수행 할 수 있습니다.

$ ./tool --list "[1,2,3,4]"


답변

내부 목록의 유형과 길이가 다른 중첩 목록이 있고 유형을 유지하려는 경우 (예 :

[[1, 2], ["foo", "bar"], [3.14, "baz", 20]]

당신은에 의해 제안 된 솔루션을 사용할 수 있습니다 SAM-메이슨 @를이 질문에 아래와 같이 :

from argparse import ArgumentParser
import json

parser = ArgumentParser()
parser.add_argument('-l', type=json.loads)
parser.parse_args(['-l', '[[1,2],["foo","bar"],[3.14,"baz",20]]'])

이것은 다음을 제공합니다.

Namespace(l=[[1, 2], ['foo', 'bar'], [3.14, 'baz', 20]])