programing

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

javaba 2022. 9. 30. 10:59
반응형

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"

단답

하다를 사용하세요.nargs option.'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='*'소요됩니다.

추가하다

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=listargparse 도..★★★★★★ 。


장황한 답변

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

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 및 positional 인수.argparse는 옵션에 대해 예상되는 값의 수를 정확하게 알 수 있습니다.
  • 명령줄에1 따옴표 사용 안 함
  • 마세요type=list리스트가 반환되기 때문에
    • 은 후드 에 있기 때문에 합니다.argparse의 값을 합니다.type당신이 선택한 주장을 각 개인에게 강요하는 것type이치노
    • 하시면 됩니다.type=int

1:일반적으로 말하는게 아니라.. 말은, 목록을 전달하기 위해 인용문을 사용하는 것은 당신이 원하는 것이 아니라는 것이다.

구분된 문자열을 전달하는 것이 좋습니다.이 문자열은 나중에 스크립트에서 해석할 수 있습니다. 수 때문입니다.목록의 유형은 다양합니다.int ★★★★★★★★★★★★★★★★★」str 을 사용하기도 합니다.nargs옵션 인수와 위치 인수가 여러 개 있는 경우 문제가 발생합니다.

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]

정상적으로 동작합니다.딜리미터는 공백일 수도 있습니다.이 경우 질문의 예시와 같이 인수 값 주위에 따옴표를 붙입니다.

또는 Chepner의 설명에 제시된 람다 유형을 사용할 수 있습니다.

parser.add_argument('-l', '--list', help='delimited list input', 
    type=lambda s: [int(item) for item in s.split(',')])

또한 목록을 미리 알고 있는 경우 를 사용할 수 있습니다.

>>> 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 매개 변수 사용

용 i i i i를 쓴다.nargs='*'add_parameter로 합니다.는 특별히 ★★★★★★★★★★★★★★★★★★★를 사용했습니다.nargs='*'[ I any explicit arguments ]가 아닌 을 설정합니다.

코드 스니펫을 예로 들 수 있습니다.

예: temp_args1.화이

주의사항:아래 샘플 코드는 python3으로 작성되어 있습니다.print statement 형식을 변경하여 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))

되어 있는 .- 주 : 록 、 목 、 note note 、 note that that that that that 。opts.alist, '정수'의 합니다.parser.add_argument로로 합니다.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']

복수의 는, 1 의 「」를합니다.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='lst',      # store in 'lst'.
    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(lst=[123, 234, 345, 456])
Namespace(lst=[456])  # Attention!

번 「」)이 됩니다.'store'는 기존 는 기존 데이터를 대체합니다.

다른 은 '먹다'를 입니다.append★★★★

a = argparse.ArgumentParser()
a.add_argument(
    '-l', '--list',  # either of this switches
    type=int,        # /parameters/ are ints
    dest='lst',      # store in 'lst'.
    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(lst=[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]"

가장 우아한 해결책은 Chepner가 언급한 대로 람다 함수를 "type"으로 전환하는 것이라고 생각합니다.또, 리스트의 딜리미터를 사전에 모르는 경우는, 복수의 딜리미터를 re.split 에 건네줄 수도 있습니다.

# python3 test.py -l "abc xyz, 123"

import re
import argparse

parser = argparse.ArgumentParser(description='Process a list.')
parser.add_argument('-l', '--list',
                    type=lambda s: re.split(' |, ', s),
                    required=True,
                    help='comma or space delimited list of characters')

args = parser.parse_args()
print(args.list)


# Output: ['abc', 'xyz', '123']

JSON 리스트 솔루션

명령줄을 통해 전달 목록(dicts)을 처리하는 좋은 방법은 json을 사용하는 것입니다.이를 통해 json을 해석하기 위해 별도의 단계를 필요로 하는 대신 argparse 파싱이 간소화됩니다.

# parse_list.py
import argparse
import json

parser = argparse.ArgumentParser()
parser.add_argument('-l', '--list', type=str)
args = parser.parse_args()
# parse string json input to python list
parsed_list = json.loads(args.list)
print(parsed_list)

사용 예

$ python parse_list.py -l "[265340, 268738, 270774, 270817]"
[265340, 268738, 270774, 270817]

내부 리스트의 유형과 길이가 다른 중첩 리스트가 있는 경우, 예를 들어 예를 들어 다음과 같이 유형을 보존할 수 있습니다.

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

그러면 다음 질문에 대해 @sam-timeout이 제안한 솔루션을 사용할 수 있습니다.

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]])

해, 「」를 할 수 .eval목록으로 읽을 수 있는 기본 제공 함수입니다.이 경우 스트링 해석에 성공하려면 작은 따옴표를 큰따옴표로 묶어야 합니다(또는 그 반대).

# declare the list arg as a string
parser.add_argument('-l', '--list', type=str)

# parse
args = parser.parse()

# turn the 'list' string argument into a list object
args.list = eval(args.list)
print(list)
print(type(list))

테스트:

python list_arg.py --list "[1, 2, 3]"

[1, 2, 3]
<class 'list'>

여러 목록, 정수 값 및 문자열을 전달하고 싶습니다.

유용한 링크 => Bash 변수를 Python에 전달하는 방법

def main(args):
    my_args = []
    for arg in args:
        if arg.startswith("[") and arg.endswith("]"):
            arg = arg.replace("[", "").replace("]", "")
            my_args.append(arg.split(","))
        else:
            my_args.append(arg)

    print(my_args)


if __name__ == "__main__":
    import sys
    main(sys.argv[1:])

순서는 중요하지 않다.는, 「중간」과 해 ."[" ★★★★★★★★★★★★★★★★★」"]쉼표로 구분합니다.

그리고나서,

python test.py my_string 3 "[1,2]" "[3,4,5]"

= > 력> = >['my_string', '3', ['1', '2'], ['3', '4', '5']],my_args는 인수를 순서대로 포함합니다

하면 action='append' defaultArgparse는 사용자가 예상할 수도 있고 예상하지 못할 수도 있는 기본값을 대체하는 대신 지정된 기본값에 추가하려고 시도합니다.

있습니다.action='append 를 들어 Argparse Docs에 기재되어 있습니다.이 경우 예상대로 동작합니다.

>> import argparse
>> parser = argparse.ArgumentParser()
>> parser.add_argument('--foo', action='append')
>> parser.parse_args('--foo 1 --foo 2'.split())

Out[2]: Namespace(foo=['1', '2'])

다만, 디폴트치를 지정하도록 선택하면, Argparse 의 「추가」액션은, 디폴트치를 치환하는 것이 아니고, 지정된 디폴트치에 추가하려고 합니다.

import argparse
REASONABLE_DEFAULTS = ['3', '4']
parser = argparse.ArgumentParser()
parser.add_argument('--foo', default=REASONABLE_DEFAULTS,action='append')
parser.parse_args('--foo 1 --foo 2'.split())

Out[6]: Namespace(foo=['3', '4', '1', '2'])

Argparse가 기본값(리스트가 아닌 기본값으로 태플을 전달하는 등)을 대체할 으로 예상한 경우 다음과 같은 혼란스러운 오류가 발생할 수 있습니다.

import argparse
REASONABLE_DEFAULTS = ('3', '4')
parser = argparse.ArgumentParser()
parser.add_argument('--foo', default=REASONABLE_DEFAULTS,action='append')
parser.parse_args('--foo 1 --foo 2'.split())

AttributeError: 'tuple' object has no attribute 'append'

예기치 않은 동작을 추적하는 버그가 있지만 2012년부터이기 때문에 해결될 것 같지 않습니다.

Lunguini의 답변에 Chepner의 코멘트를 적용합니다.

import argparse, json                                                                                            
parser = argparse.ArgumentParser()                                                                               
parser.add_argument('-l', '--list', type=lambda a: json.loads(a), default="[]",                                  
                    help="String formatted as list wrapped in []")                                               
args = parser.parse_args()                                                                                       
print(args.list)                                                                                                 

사용방법:

$ python parse_list.py -l "[265340, 268738, 270774, 270817]"
[265340, 268738, 270774, 270817]

언급URL : https://stackoverflow.com/questions/15753701/how-can-i-pass-a-list-as-a-command-line-argument-with-argparse

반응형