파이썬 argparse를 사용하여 여러 중첩 하위 명령을 구문 분석하는 방법은 무엇입니까?


82

다음과 같은 인터페이스가있는 명령 줄 프로그램을 구현하고 있습니다.

cmd [GLOBAL_OPTIONS] {command [COMMAND_OPTS]} [{command [COMMAND_OPTS]} ...]

나는 argparse 문서를 살펴 보았다 . in을 GLOBAL_OPTIONS사용하여 선택적 인수로 구현할 수 있습니다 . 그리고 using 하위 명령add_argumentargparse{command [COMMAND_OPTS]} .

문서에서 하나의 하위 명령 만 가질 수있는 것 같습니다. 그러나 보시다시피 하나 이상의 하위 명령을 구현해야합니다. 사용하는 명령 줄 인수를 구문 분석하는 가장 좋은 방법은 무엇입니까 argparse?


2
나는 이것이 하위 명령이 의도 한 것이라고 생각하지 않습니다. 문서에서 이것은 본질적으로 별개의 개별 서브 프로그램 을 제어하기위한 것임을 명시합니다 . 논쟁 그룹 을 살펴 보셨습니까 ?
Chris

distutils ./setup.py에는 이러한 스타일의 CLI 인터페이스도 있으므로 소스 코드를 살펴 보는 것도 흥미로울 것입니다.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

답변:


27

나는 같은 질문을 내 놓았고 더 나은 답을 얻은 것 같습니다.

해결책은 단순히 다른 하위 구문 분석기와 하위 구문 분석기를 중첩하는 것이 아니라 다른 하위 구문 분석기 다음에 구문 분석기를 추가하여 하위 구문 분석기를 추가 할 수 있다는 것입니다.

코드는 방법을 알려줍니다.

parent_parser = argparse.ArgumentParser(add_help=False)                                                                                                  
parent_parser.add_argument('--user', '-u',                                                                                                               
                    default=getpass.getuser(),                                                                                                           
                    help='username')                                                                                                                     
parent_parser.add_argument('--debug', default=False, required=False,                                                                                     
                           action='store_true', dest="debug", help='debug flag')                                                                         
main_parser = argparse.ArgumentParser()                                                                                                                  
service_subparsers = main_parser.add_subparsers(title="service",                                                                                         
                    dest="service_command")                                                                                                              
service_parser = service_subparsers.add_parser("first", help="first",                                                                                    
                    parents=[parent_parser])                                                                                                             
action_subparser = service_parser.add_subparsers(title="action",                                                                                         
                    dest="action_command")                                                                                                               
action_parser = action_subparser.add_parser("second", help="second",                                                                                     
                    parents=[parent_parser])                                                                                                             

args = main_parser.parse_args()   

예, argparse중첩 된 하위 구문 분석기를 허용합니다. 그러나 나는 그것들이 다른 곳에서만 사용되는 것을 보았다 – 파이썬 문제에 대한 테스트 케이스 인 bugs.python.org/issue14365
hpaulj

9
이것은 명령에 중첩 된 구조가 있다고 가정합니다. 하지만 질문은 "병렬"명령을 요구하는 것입니다
augurar

25

@mgilson 은이 질문에 대한 좋은 대답 을 가지고 있습니다. 그러나 sys.argv를 나 자신이 분할하는 문제는 Argparse가 사용자를 위해 생성하는 모든 멋진 도움말 메시지를 잃어버린다는 것입니다. 그래서 나는 이것을 끝냈다.

import argparse

## This function takes the 'extra' attribute from global namespace and re-parses it to create separate namespaces for all other chained commands.
def parse_extra (parser, namespace):
  namespaces = []
  extra = namespace.extra
  while extra:
    n = parser.parse_args(extra)
    extra = n.extra
    namespaces.append(n)

  return namespaces

argparser=argparse.ArgumentParser()
subparsers = argparser.add_subparsers(help='sub-command help', dest='subparser_name')

parser_a = subparsers.add_parser('command_a', help = "command_a help")
## Setup options for parser_a

## Add nargs="*" for zero or more other commands
argparser.add_argument('extra', nargs = "*", help = 'Other commands')

## Do similar stuff for other sub-parsers

이제 첫 번째 구문 분석 후 모든 연결 명령이 extra. 모든 연결 명령을 가져오고 별도의 네임 스페이스를 만드는 것이 비어 있지 않은 동안 다시 구문 분석합니다. 그리고 argparse가 생성하는 더 좋은 사용 문자열을 얻습니다.


2
내가 도착 후 @Flavius는 namespace호출하여 파서에서 namespace = argparser.parse_args(), 나는 전화 parse_extraparsernamespace. extra_namespaces = parse_extra( argparser, namespace )
Vikas 2013 년

나는 논리를 이해한다고 생각하지만, parser당신이 가지고있는 코드 에는 무엇이 있습니다. 나는 그것이 extra인수 를 추가하는 데 사용되는 것을 본다 . 그런 다음 위의 의견에서 다시 언급했습니다. 그럴까요 argparser?
jmlopez

@jmlopez 네 그래야합니다 argparser. 편집합니다.
Vikas

1
이 솔루션은 하위 명령 별 선택적 인수에 대해 실패합니다. 대체 솔루션은 아래 내 솔루션 ( stackoverflow.com/a/49977713/428542 )을 참조하십시오 .
MacFreek

1
다음은 이것이 실패하는 방법의 예입니다. 다음 3 줄을 추가합니다. parser_b = subparsers.add_parser('command_b', help='command_b help'); parser_b.add_argument('--baz', choices='XYZ', help='baz help'); options = argparser.parse_args(['--foo', 'command_a', 'command_b', '--baz', 'Z']); 이것은 오류와 함께 실패합니다 PROG: error: unrecognized arguments: --baz Z. 그 이유는의 구문 분석 중에의 command_a선택적 인수 command_b가 이미 구문 분석되었으며의 하위 구문 분석기에 대해 알려지지 않았기 때문입니다 command_a.
MacFreek

14

parse_known_args네임 스페이스와 알 수없는 문자열 목록을 반환합니다. 이것은 extra확인 된 답변 과 유사합니다 .

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
sub = parser.add_subparsers()
for i in range(1,4):
    sp = sub.add_parser('cmd%i'%i)
    sp.add_argument('--foo%i'%i) # optionals have to be distinct

rest = '--foo 0 cmd2 --foo2 2 cmd3 --foo3 3 cmd1 --foo1 1'.split() # or sys.argv
args = argparse.Namespace()
while rest:
    args,rest =  parser.parse_known_args(rest,namespace=args)
    print args, rest

생성 :

Namespace(foo='0', foo2='2') ['cmd3', '--foo3', '3', 'cmd1', '--foo1', '1']
Namespace(foo='0', foo2='2', foo3='3') ['cmd1', '--foo1', '1']
Namespace(foo='0', foo1='1', foo2='2', foo3='3') []

대체 루프는 각 하위 파서에 자체 네임 스페이스를 제공합니다. 이렇게하면 위치 이름이 겹칠 수 있습니다.

argslist = []
while rest:
    args,rest =  parser.parse_known_args(rest)
    argslist.append(args)

잘 작동합니다. 그러나 결함이 있습니다. 어딘가에 맞춤법이 틀린 옵션 (예 rest = '--foo 0 cmd2 --foo2 2 --bar cmd3 --foo3 3 cmd1 --foo1 1'.split():)이 있으면 argparse가 error: too few arguments잘못된 옵션을 가리키는 대신로 끝납니다 . 이것은 rest우리가 명령 인수에서 벗어날 때까지 잘못된 옵션이 남아 있기 때문 입니다.
Adrian W

이 의견은 # or sys.argv해야한다 # or sys.argv[1:].
Adrian W

5

언제든지 명령 줄을 직접 분할 ( sys.argv명령 이름으로 분할 ) 한 다음 특정 명령에 해당하는 부분 만 전달할 parse_args수 있습니다 Namespace. 원하는 경우 네임 스페이스 키워드를 사용하여 동일한 것을 사용할 수도 있습니다 .

다음을 사용하면 명령 줄을 쉽게 그룹화 할 수 있습니다 itertools.groupby.

import sys
import itertools
import argparse    

mycommands=['cmd1','cmd2','cmd3']

def groupargs(arg,currentarg=[None]):
    if(arg in mycommands):currentarg[0]=arg
    return currentarg[0]

commandlines=[list(args) for cmd,args in intertools.groupby(sys.argv,groupargs)]

#setup parser here...
parser=argparse.ArgumentParser()
#...

namespace=argparse.Namespace()
for cmdline in commandlines:
    parser.parse_args(cmdline,namespace=namespace)

#Now do something with namespace...

테스트되지 않은


1
감사합니다 mgilson. 이것은 내 질문에 대한 좋은 해결책이지만 조금 다르게 수행했습니다. 나는 또 다른 대답을 추가했다 .
Vikas

1
의 좋은 사용 itertools.groupby()! 이것이 내가 알기 전에 똑같은 일을 한 방법 groupby()입니다.
kzyapkov

5

@mgilson의 답변을 개선하기 위해 argv를 부분으로 분할하고 명령 인수 값을 네임 스페이스 계층 구조에 넣는 작은 구문 분석 방법을 작성했습니다.

import sys
import argparse


def parse_args(parser, commands):
    # Divide argv by commands
    split_argv = [[]]
    for c in sys.argv[1:]:
        if c in commands.choices:
            split_argv.append([c])
        else:
            split_argv[-1].append(c)
    # Initialize namespace
    args = argparse.Namespace()
    for c in commands.choices:
        setattr(args, c, None)
    # Parse each command
    parser.parse_args(split_argv[0], namespace=args)  # Without command
    for argv in split_argv[1:]:  # Commands
        n = argparse.Namespace()
        setattr(args, argv[0], n)
        parser.parse_args(argv, namespace=n)
    return args


parser = argparse.ArgumentParser()
commands = parser.add_subparsers(title='sub-commands')

cmd1_parser = commands.add_parser('cmd1')
cmd1_parser.add_argument('--foo')

cmd2_parser = commands.add_parser('cmd2')
cmd2_parser.add_argument('--foo')

cmd2_parser = commands.add_parser('cmd3')
cmd2_parser.add_argument('--foo')


args = parse_args(parser, commands)
print(args)

제대로 작동하여 멋진 argparse 도움말을 제공합니다.

대상 ./test.py --help:

usage: test.py [-h] {cmd1,cmd2,cmd3} ...

optional arguments:
  -h, --help        show this help message and exit

sub-commands:
  {cmd1,cmd2,cmd3}

대상 ./test.py cmd1 --help:

usage: test.py cmd1 [-h] [--foo FOO]

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO

그리고 인수 값을 포함하는 네임 스페이스 계층을 생성합니다.

./test.py cmd1 --foo 3 cmd3 --foo 4
Namespace(cmd1=Namespace(foo='3'), cmd2=None, cmd3=Namespace(foo='4'))

위의 코드를 검토 한 결과 한 가지 문제가 발생했습니다. 라인 (18)에, 당신은 참조 split_argv[0]이는 실제로 빈 split_argv당신이 추가하기 때문에, [c]하기 split_argv(intially로 설정 [[]]). 7 행을로 변경하면 split_argv = []모든 것이 예상대로 작동합니다.
HEADLESS_0NE

2
나는 당신이 공유 한 코드를 (다시) 몇 가지 더 수정했고 (내가 겪었던
HEADLESS_0NE

이 답변은 꽤 괜찮은, 당신이 결정할 수 있습니다 subparser받는 이명 령을 추가하여 사용 add_subparsers방법 stackoverflow.com/questions/8250010/...
wizebin

5

@Vikas가 제공하는 솔루션은 하위 명령 별 선택적 인수에 대해 실패하지만 접근 방식은 유효합니다. 다음은 개선 된 버전입니다.

import argparse

# create the top-level parser
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('--foo', action='store_true', help='foo help')
subparsers = parser.add_subparsers(help='sub-command help', dest='subparser_name')

# create the parser for the "command_a" command
parser_a = subparsers.add_parser('command_a', help='command_a help')
parser_a.add_argument('bar', type=int, help='bar help')

# create the parser for the "command_b" command
parser_b = subparsers.add_parser('command_b', help='command_b help')
parser_b.add_argument('--baz', choices='XYZ', help='baz help')

# parse some argument lists
argv = ['--foo', 'command_a', '12', 'command_b', '--baz', 'Z']
while argv:
    print(argv)
    options, argv = parser.parse_known_args(argv)
    print(options)
    if not options.subparser_name:
        break

이것은 사용하는 parse_known_args대신 parse_args. parse_args현재 서브 파서에 알려지지 않은 인수가 발견되는 즉시 중단됩니다.parse_known_args , 반환 된 튜플의 두 번째 값으로 반환됩니다. 이 접근 방식에서는 나머지 인수가 파서에 다시 공급됩니다. 따라서 각 명령에 대해 새 네임 스페이스가 생성됩니다.

이 기본 예에서 모든 전역 옵션은 첫 번째 옵션 네임 스페이스에만 추가되며 후속 네임 스페이스에는 추가되지 않습니다.

이 접근 방식은 대부분의 상황에서 잘 작동하지만 세 가지 중요한 제한 사항이 있습니다.

  • 같은 다른 하위 명령에 대해 동일한 선택적 인수를 사용할 수 없습니다 myprog.py command_a --foo=bar command_b --foo=bar.
  • 부속 명령 ( nargs='?'또는 nargs='+'또는 nargs='*') 과 함께 가변 길이 위치 인수를 사용할 수 없습니다 .
  • 알려진 인수는 새 명령에서 '중단'없이 구문 분석됩니다. 예 PROG --foo command_b command_a --baz Z 12를 들어 위의 코드에서는에서 --baz Z가 아니라에서 소비 command_b됩니다 command_a.

이러한 제한은 argparse의 직접적인 제한입니다. 다음은 단일 하위 명령을 사용하는 경우에도 argparse의 제한 사항을 보여주는 간단한 예입니다.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('spam', nargs='?')
subparsers = parser.add_subparsers(help='sub-command help', dest='subparser_name')

# create the parser for the "command_a" command
parser_a = subparsers.add_parser('command_a', help='command_a help')
parser_a.add_argument('bar', type=int, help='bar help')

# create the parser for the "command_b" command
parser_b = subparsers.add_parser('command_b', help='command_b help')

options = parser.parse_args('command_a 42'.split())
print(options)

이것은 error: argument subparser_name: invalid choice: '42' (choose from 'command_a', 'command_b').

원인은 내부 방법 argparse.ArgParser._parse_known_args()이 너무 탐욕스럽고 그것이 command_a선택적인 spam인수 의 값 이라고 가정하기 때문 입니다 . 특히, 선택적 및 위치 인수를 '분할'할 때 _parse_known_args()arugment의 이름 (예 : command_a또는 command_b)을 보지 않고 인수 목록에서 발생하는 위치 만 확인합니다. 또한 모든 하위 명령이 나머지 인수를 모두 사용한다고 가정합니다. 이 제한은 argparse또한 다중 명령 하위 구문 분석기의 적절한 구현을 방해합니다. 이는 안타깝게도 적절한 구현을 위해서는 argparse.ArgParser._parse_known_args()메서드를 완전히 다시 작성해야하며 이는 200 줄 이상의 코드가 필요함을 의미합니다 .

이러한 제한을 감안할 때 하위 명령 대신 단일 객관식 인수로 간단히 되 돌리는 옵션이 될 수 있습니다.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--bar', type=int, help='bar help')
parser.add_argument('commands', nargs='*', metavar='COMMAND',
                 choices=['command_a', 'command_b'])

options = parser.parse_args('--bar 2 command_a command_b'.split())
print(options)
#options = parser.parse_args(['--help'])

사용 정보에 다른 명령을 나열하는 것도 가능합니다. 내 대답 https://stackoverflow.com/a/49999185/428542를 참조하십시오.


4

arghandler 시도해 볼 수 있습니다. 이것은 부속 명령을 명시 적으로 지원하는 argparse의 확장입니다.


3
arghandler는 하위 명령을 선언하는 좋은 방법을 제공합니다. 그러나 이것이 어떻게 OP의 질문을 해결하는 데 도움이되는지 모르겠습니다 . 여러 하위 명령 구문 분석 . 구문 분석 된 첫 번째 하위 명령은 나머지 인수를 모두 소모하므로 추가 명령은 구문 분석되지 않습니다. arghandler로 이것을 해결하는 방법에 대한 힌트를주십시오. 감사.
Adrian W

1

병렬 파서를 지원하는 또 다른 패키지는 "declarative_parser"입니다.

import argparse
from declarative_parser import Parser, Argument

supported_formats = ['png', 'jpeg', 'gif']

class InputParser(Parser):
    path = Argument(type=argparse.FileType('rb'), optional=False)
    format = Argument(default='png', choices=supported_formats)

class OutputParser(Parser):
    format = Argument(default='jpeg', choices=supported_formats)

class ImageConverter(Parser):
    description = 'This app converts images'

    verbose = Argument(action='store_true')
    input = InputParser()
    output = OutputParser()

parser = ImageConverter()

commands = '--verbose input image.jpeg --format jpeg output --format gif'.split()

namespace = parser.parse_args(commands)

네임 스페이스는 다음과 같습니다.

Namespace(
    input=Namespace(format='jpeg', path=<_io.BufferedReader name='image.jpeg'>),
    output=Namespace(format='gif'),
    verbose=True
)

면책 조항 : 나는 저자입니다. Python 3.6이 필요합니다. 사용을 설치하려면 :

pip3 install declarative_parser

여기에 문서가 있고 여기 에 GitHub저장소가 있습니다 .


1

하위 구문 분석기 를 사용하여 전체 Python 2/3 예제를 빌드parse_known_args 하고 parse_args( IDEone 에서 실행 ) :

from __future__ import print_function

from argparse import ArgumentParser
from random import randint


def main():
    parser = get_parser()

    input_sum_cmd = ['sum_cmd', '--sum']
    input_min_cmd = ['min_cmd', '--min']

    args, rest = parser.parse_known_args(
        # `sum`
        input_sum_cmd +
        ['-a', str(randint(21, 30)),
         '-b', str(randint(51, 80))] +
        # `min`
        input_min_cmd +
        ['-y', str(float(randint(64, 79))),
         '-z', str(float(randint(91, 120)) + .5)]
    )

    print('args:\t ', args,
          '\nrest:\t ', rest, '\n', sep='')

    sum_cmd_result = args.sm((args.a, args.b))
    print(
        'a:\t\t {:02d}\n'.format(args.a),
        'b:\t\t {:02d}\n'.format(args.b),
        'sum_cmd: {:02d}\n'.format(sum_cmd_result), sep='')

    assert rest[0] == 'min_cmd'
    args = parser.parse_args(rest)
    min_cmd_result = args.mn((args.y, args.z))
    print(
        'y:\t\t {:05.2f}\n'.format(args.y),
        'z:\t\t {:05.2f}\n'.format(args.z),
        'min_cmd: {:05.2f}'.format(min_cmd_result), sep='')

def get_parser():
    # create the top-level parser
    parser = ArgumentParser(prog='PROG')
    subparsers = parser.add_subparsers(help='sub-command help')

    # create the parser for the "sum" command
    parser_a = subparsers.add_parser('sum_cmd', help='sum some integers')
    parser_a.add_argument('-a', type=int,
                          help='an integer for the accumulator')
    parser_a.add_argument('-b', type=int,
                          help='an integer for the accumulator')
    parser_a.add_argument('--sum', dest='sm', action='store_const',
                          const=sum, default=max,
                          help='sum the integers (default: find the max)')

    # create the parser for the "min" command
    parser_b = subparsers.add_parser('min_cmd', help='min some integers')
    parser_b.add_argument('-y', type=float,
                          help='an float for the accumulator')
    parser_b.add_argument('-z', type=float,
                          help='an float for the accumulator')
    parser_b.add_argument('--min', dest='mn', action='store_const',
                          const=min, default=0,
                          help='smallest integer (default: 0)')
    return parser


if __name__ == '__main__':
    main()

0

필자는 어느 정도 동일한 요구 사항이있었습니다. 전역 인수를 설정할 수 있고 명령을 연결하고 명령 줄 순서대로 실행할 수 있어야합니다 .

나는 다음 코드로 끝났다. 이 스레드와 다른 스레드의 코드 일부를 사용했습니다.

# argtest.py
import sys
import argparse

def init_args():

    def parse_args_into_namespaces(parser, commands):
        '''
        Split all command arguments (without prefix, like --) in
        own namespaces. Each command accepts extra options for
        configuration.
        Example: `add 2 mul 5 --repeat 3` could be used to a sequencial
                 addition of 2, then multiply with 5 repeated 3 times.
        '''
        class OrderNamespace(argparse.Namespace):
            '''
            Add `command_order` attribute - a list of command
            in order on the command line. This allows sequencial
            processing of arguments.
            '''
            globals = None
            def __init__(self, **kwargs):
                self.command_order = []
                super(OrderNamespace, self).__init__(**kwargs)

            def __setattr__(self, attr, value):
                attr = attr.replace('-', '_')
                if value and attr not in self.command_order:
                    self.command_order.append(attr)
                super(OrderNamespace, self).__setattr__(attr, value)

        # Divide argv by commands
        split_argv = [[]]
        for c in sys.argv[1:]:
            if c in commands.choices:
                split_argv.append([c])
            else:
                split_argv[-1].append(c)

        # Globals arguments without commands
        args = OrderNamespace()
        cmd, args_raw = 'globals', split_argv.pop(0)
        args_parsed = parser.parse_args(args_raw, namespace=OrderNamespace())
        setattr(args, cmd, args_parsed)

        # Split all commands to separate namespace
        pos = 0
        while len(split_argv):
            pos += 1
            cmd, *args_raw = split_argv.pop(0)
            assert cmd[0].isalpha(), 'Command must start with a letter.'
            args_parsed = commands.choices[cmd].parse_args(args_raw, namespace=OrderNamespace())
            setattr(args, f'{cmd}~{pos}', args_parsed)

        return args


    #
    # Supported commands and options
    #
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    parser.add_argument('--print', action='store_true')

    commands = parser.add_subparsers(title='Operation chain')

    cmd1_parser = commands.add_parser('add', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    cmd1_parser.add_argument('add', help='Add this number.', type=float)
    cmd1_parser.add_argument('-r', '--repeat', help='Repeat this operation N times.',
                                               default=1, type=int)

    cmd2_parser = commands.add_parser('mult', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    cmd2_parser.add_argument('mult', help='Multiply with this number.', type=float)
    cmd2_parser.add_argument('-r', '--repeat', help='Repeat this operation N times.',
                                               default=1, type=int)

    args = parse_args_into_namespaces(parser, commands)
    return args


#
# DEMO
#

args = init_args()

# print('Parsed arguments:')
# for cmd in args.command_order:
#     namespace = getattr(args, cmd)
#     for option_name in namespace.command_order:
#         option_value = getattr(namespace, option_name)
#         print((cmd, option_name, option_value))

print('Execution:')
result = 0
for cmd in args.command_order:
    namespace = getattr(args, cmd)
    cmd_name, cmd_position = cmd.split('~') if cmd.find('~') > -1 else (cmd, 0)
    if cmd_name == 'globals':
        pass
    elif cmd_name == 'add':
        for r in range(namespace.repeat):
            if args.globals.print:
                print(f'+ {namespace.add}')
            result = result + namespace.add
    elif cmd_name == 'mult':
        for r in range(namespace.repeat):
            if args.globals.print:
                print(f'* {namespace.mult}')
            result = result * namespace.mult
    else:
        raise NotImplementedError(f'Namespace `{cmd}` is not implemented.')
print(10*'-')
print(result)

아래 예 :

$ python argstest.py --print add 1 -r 2 mult 5 add 3 mult -r 5 5

Execution:
+ 1.0
+ 1.0
* 5.0
+ 3.0
* 5.0
* 5.0
* 5.0
* 5.0
* 5.0
----------
40625.0

-4

optparse 패키지를 사용할 수 있습니다.

import optparse
parser = optparse.OptionParser()
parser.add_option("-f", dest="filename", help="corpus filename")
parser.add_option("--alpha", dest="alpha", type="float", help="parameter alpha", default=0.5)
(options, args) = parser.parse_args()
fname = options.filename
alpha = options.alpha

1
이것은 실제로 질문에 대한 답이 아닙니다. 또한 optparse는 더 이상 사용되지 않습니다 ( python 문서 "optparse 모듈은 더 이상 사용되지 않으며 더 이상 개발되지 않습니다. 개발은 argparse 모듈로 계속됩니다").
Chris

반대 투표에 대해 죄송하지만 이것은 내가 요청한 질문을 해결하지 않습니다.
Vikas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.