이것은 간단한 것일 수 있습니다. argparse를 사용하여 명령 줄 인수 / 옵션을 처리하는 프로그램이 있다고 가정합니다. 다음은 '도움말'메시지를 인쇄합니다.
./myprogram -h
또는:
./myprogram --help
그러나 인수없이 스크립트를 실행하면 아무것도하지 않습니다. 내가 원하는 것은 인수없이 호출 될 때 사용법 메시지를 표시하는 것입니다. 어떻게됩니까?
이것은 간단한 것일 수 있습니다. argparse를 사용하여 명령 줄 인수 / 옵션을 처리하는 프로그램이 있다고 가정합니다. 다음은 '도움말'메시지를 인쇄합니다.
./myprogram -h
또는:
./myprogram --help
그러나 인수없이 스크립트를 실행하면 아무것도하지 않습니다. 내가 원하는 것은 인수없이 호출 될 때 사용법 메시지를 표시하는 것입니다. 어떻게됩니까?
답변:
이 답변은 Google 그룹의 Steven Bethard 가 제공합니다 . Google 계정이없는 사용자가 더 쉽게 액세스 할 수 있도록 여기에 다시 게시하고 있습니다.
error
메소드 의 기본 동작을 대체 할 수 있습니다 .
import argparse
import sys
class MyParser(argparse.ArgumentParser):
def error(self, message):
sys.stderr.write('error: %s\n' % message)
self.print_help()
sys.exit(2)
parser = MyParser()
parser.add_argument('foo', nargs='+')
args = parser.parse_args()
위의 솔루션은 error
메소드가 트리거 될 때마다 도움말 메시지를 인쇄합니다 . 예를 들어, 유효한 옵션이 아닌 test.py --blah
경우 도움말 메시지도 인쇄합니다 --blah
.
명령 행에 인수가 제공되지 않은 경우에만 도움말 메시지를 인쇄하려는 경우 여전히 가장 쉬운 방법입니다.
import argparse
import sys
parser=argparse.ArgumentParser()
parser.add_argument('foo', nargs='+')
if len(sys.argv)==1:
parser.print_help(sys.stderr)
sys.exit(1)
args=parser.parse_args()
참고 parser.print_help()
기본적으로 표준 출력으로 인쇄합니다. init_js가 제안 했듯이 parser.print_help(sys.stderr)
stderr에 인쇄하는 데 사용하십시오 .
parser.print_usage()
대신 사용하는 두 번째 솔루션 parser.print_help()
-도움말 메시지에 사용법이 포함되어 있지만 더 자세합니다.
error()
는 나에게 끔찍한 생각 인 것 같습니다. 다른 용도로 사용되며 친숙한 사용법이나 도움말을 인쇄하도록 설계되지 않았습니다.
클래스를 작성하는 대신 try / except를 대신 사용할 수 있습니다.
try:
options = parser.parse_args()
except:
parser.print_help()
sys.exit(0)
단점은 워크 플로가 더 명확하고 스텁 클래스가 필요 없다는 것입니다. 단점은 첫 번째 '사용'줄이 두 번 인쇄된다는 것입니다.
이것은 적어도 하나의 필수 주장이 필요합니다. 필수 인수가 없으면 명령 행에서 0 개의 인수를 제공하는 것이 유효합니다.
-h
플래그를 사용 하면 도움말을 두 번 인쇄하고 플래그를 사용하면 불필요한 인쇄 도움말을 인쇄합니다 --version
. 이러한 문제를 완화하기 위해 다음과 같은 오류 유형을 확인할 수 있습니다.except SystemExit as err: if err.code == 2: parser.print_help()
스크립트를 실행하기 위해 지정해야하는 인수가있는 경우 다음 과 같이 ArgumentParser에 필요한 매개 변수를 사용하십시오 .
parser.add_argument('--foo', required=True)
인수없이 스크립트를 실행하면 parse_args ()가 오류를보고합니다.
아래 add_subparsers
에 언급 된 것처럼 (하위) 파서에 대한 기본 기능을 연결 하면 간단히 기본 작업으로 추가 할 수 있습니다.
parser = argparse.ArgumentParser()
parser.set_defaults(func=lambda x: parser.print_usage())
args = parser.parse_args()
args.func(args)
위치 인수가 누락되어 예외가 발생하면 try-except를 추가하십시오.
가장 깨끗한 해결책은 명령 줄에 기본 인수가 없으면 수동으로 기본 인수를 전달하는 것입니다.
parser.parse_args(args=None if sys.argv[1:] else ['--help'])
완전한 예 :
import argparse, sys
parser = argparse.ArgumentParser()
parser.add_argument('--host', default='localhost', help='Host to connect to')
# parse arguments
args = parser.parse_args(args=None if sys.argv[1:] else ['--help'])
# use your args
print("connecting to {}".format(args.host))
인수없이 호출되면 완전한 도움말 (짧은 사용법이 아님)을 인쇄합니다.
sys.argv[1:]
매우 일반적인 관용구입니다. 나는 parser.parse_args(None if sys.argv[1:] else ['-h'])
더 관용적이고 더 깨끗합니다.
내 버전을 더미에 던지기 :
import argparse
parser = argparse.ArgumentParser()
args = parser.parse_args()
if not vars(args):
parser.print_help()
parser.exit(1)
당신은 알 수 있습니다 parser.exit
- sys
파일에서 유일한 이유라면 가져 오기 줄을 저장하기 때문에 주로 그렇게 합니다 ...
not vars(args)
인수에 default
메소드 가 있으면 작동하지 않을 수 있습니다 .
작업을 수행 할 수있는 한 줄짜리 쌍 sys.argv[1:]
(명령 줄 인수를 참조하는 매우 일반적인 파이썬 관용구 sys.argv[0]
)이 있습니다.
첫 번째는 자명하고 깨끗하며 피 토닉입니다.
args = parser.parse_args(None if sys.argv[1:] else ['-h'])
두 번째는 약간의 해커입니다. 이전에 평가 한 사실을 빈 목록이 같고 동등 하다는 것을 결합하면 False
다음 True == 1
과 False == 0
같습니다.
args = parser.parse_args([None, ['-h']][not sys.argv[1:]])
대괄호가 너무 많을 수도 있지만 이전에 인수를 선택했다면 분명합니다.
_, *av = sys.argv
args = parser.parse_args([None, ['-h']][not av])
parser.print_help()
parser.exit()
이 parser.exit
메소드는 status
(returncode) 및 message
값 (후행 줄 바꿈 포함 ) 도 허용합니다 .
의견이 많은 예 :)
#!/usr/bin/env python3
""" Example argparser based python file
"""
import argparse
ARGP = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawTextHelpFormatter,
)
ARGP.add_argument('--example', action='store_true', help='Example Argument')
def main(argp=None):
if argp is None:
argp = ARGP.parse_args() # pragma: no cover
if 'soemthing_went_wrong' and not argp.example:
ARGP.print_help()
ARGP.exit(status=128, message="\nI just don't know what went wrong, maybe missing --example condition?\n")
if __name__ == '__main__':
main() # pragma: no cover
호출 예 :
$ python3 ~ / helloworld.py; 에코 $? 사용법 : helloworld.py [-h] [-예] argparser 기반 파이썬 파일 예제 선택적 인수 : -h, --help이 도움말 메시지를 표시하고 종료 --example 인수 예 나는 단지 무엇이 잘못되었는지, 아마도 실례가 아닌지 모릅니다. 128 $ python3 ~ / helloworld.py --example; 에코 $? 0
특정 매개 변수가 전달되는 경우 도움말을 표시하려는 위치에 융통성있는 무언가가 필요한 경우 다음과 같은 다른 방법이 있습니다.
import argparse
import sys
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--days', required=False, help="Check mapped inventory that is x days old", default=None)
parser.add_argument('-e', '--event', required=False, action="store", dest="event_id",
help="Check mapped inventory for a specific event", default=None)
parser.add_argument('-b', '--broker', required=False, action="store", dest="broker_id",
help="Check mapped inventory for a broker", default=None)
parser.add_argument('-k', '--keyword', required=False, action="store", dest="event_keyword",
help="Check mapped inventory for a specific event keyword", default=None)
parser.add_argument('-p', '--product', required=False, action="store", dest="product_id",
help="Check mapped inventory for a specific product", default=None)
parser.add_argument('-m', '--metadata', required=False, action="store", dest="metadata",
help="Check mapped inventory for specific metadata, good for debugging past tix", default=None)
parser.add_argument('-u', '--update', required=False, action="store_true", dest="make_updates",
help="Update the event for a product if there is a difference, default No", default=False)
args = parser.parse_args()
days = args.days
event_id = args.event_id
broker_id = args.broker_id
event_keyword = args.event_keyword
product_id = args.product_id
metadata = args.metadata
make_updates = args.make_updates
no_change_counter = 0
change_counter = 0
req_arg = bool(days) + bool(event_id) + bool(broker_id) + bool(product_id) + bool(event_keyword) + bool(metadata)
if not req_arg:
print("Need to specify days, broker id, event id, event keyword or past tickets full metadata")
parser.print_help()
sys.exit()
elif req_arg != 1:
print("More than one option specified. Need to specify only one required option")
parser.print_help()
sys.exit()
# Processing logic here ...
건배!
명령이 사용자가 어떤 조치를 선택해야하는 항목 인 경우 required = True 인 상호 배타적 그룹을 사용하십시오. .
이것은 pd321의 답변에 대한 확장입니다.
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--batch", action='store', type=int, metavar='pay_id')
group.add_argument("--list", action='store_true')
group.add_argument("--all", action='store_true', help='check all payments')
args=parser.parse_args()
if args.batch:
print('batch {}'.format(args.batch))
if args.list:
print('list')
if args.all:
print('all')
산출:
$ python3 a_test.py
사용법 : a_test.py [-h] (--batch pay_id | --list | --all)
a_test.py : 오류 : 인수 중 하나 --batch --list --all이 필요합니다
이것은 기본적인 도움 만 제공합니다. 그리고 다른 답변 중 일부는 당신에게 완전한 도움을 줄 것입니다. 그러나 적어도 사용자는 그들이 할 수있는 알고 -h
이것은 좋지 않지만 (모든 오류를 가로 채기 때문에) :
def _error(parser):
def wrapper(interceptor):
parser.print_help()
sys.exit(-1)
return wrapper
def _args_get(args=sys.argv[1:]):
parser = argparser.ArgumentParser()
parser.error = _error(parser)
parser.add_argument(...)
...
다음은 클래스 의 error
기능에 대한 정의입니다 ArgumentParser
.
. 보시다시피 서명에 따라 두 가지 인수가 필요합니다. 그러나 클래스 외부의 함수는 첫 번째 인수에 대해 아무것도 모릅니다. self
대충 말하면 이것은 클래스의 매개 변수이기 때문입니다. 따라서, 단지 자신의 통과 (나는 ... 당신이 알고있는 것을 알고) self
과 message
의 _error(...)
(수 없습니다
def _error(self, message):
self.print_help()
sys.exit(-1)
def _args_get(args=sys.argv[1:]):
parser = argparser.ArgumentParser()
parser.error = _error
...
...
출력합니다 :
...
"AttributeError: 'str' object has no attribute 'print_help'"
). 함수를 호출하여 parser
( self
)를 전달할 수 있습니다 _error
.
def _error(self, message):
self.print_help()
sys.exit(-1)
def _args_get(args=sys.argv[1:]):
parser = argparser.ArgumentParser()
parser.error = _error(parser)
...
...
하지만 지금 프로그램을 종료하고 싶지는 않습니다. 그런 다음 반환하십시오.
def _error(parser):
def wrapper():
parser.print_help()
sys.exit(-1)
return wrapper
...
. 그럼에도 불구하고, parser
그것이 수정되었음을 알지 못하므로 오류가 발생하면 원인을 현지화 번역으로 보냅니다. 그럼 가로 채세요 :
def _error(parser):
def wrapper(interceptor):
parser.print_help()
sys.exit(-1)
return wrapper
...
. 이제 오류가 발생하여 parser
원인을 보내면 오류를 가로 채서 이것을보고 ... 버리십시오.