2013-01-02 2 views
83

제목은 내가하고 싶은 것을 요약합니다.파이썬에서 argparse를 사용하면 양의 정수만 허용

여기에 내가 가진 내용이 있습니다. 프로그램이 비항적인 정수에 불어 나지 않는 동안, 사용자에게 비항 성 정수가 기본적으로 말도 안됨을 알리 길 원합니다.

import argparse 
parser = argparse.ArgumentParser() 
parser.add_argument("-g", "--games", type=int, default=162, 
        help="The number of games to simulate") 
args = parser.parse_args() 

그리고 출력 : 음과

python simulate_many.py -g 20 
Setting up... 
Playing games... 
.................... 

출력 : 이제

python simulate_many.py -g -2 
Setting up... 
Playing games... 

, 분명히 if args.games가 부의 결정하는 경우 난 그냥를 추가 할 수 있습니다,하지만 난 경우 궁금해서 자동 사용 인쇄 기능을 활용하기 위해 레벨을 argparse 레벨로 트랩하는 방법이있었습니다. 지금은이 일을 해요 들어

python simulate_many.py -g -2 
usage: simulate_many.py [-h] [-g GAMES] [-d] [-l LEAGUE] 
simulate_many.py: error: argument -g/--games: invalid positive int value: '-2' 

, 그리고 내가 행복한 것 같아 :

python simulate_many.py -g a 
usage: simulate_many.py [-h] [-g GAMES] [-d] [-l LEAGUE] 
simulate_many.py: error: argument -g/--games: invalid int value: 'a' 

과 같이 :

이상적으로는,이 비슷한을 인쇄 할

if args.games <= 0: 
    parser.print_help() 
    print "-g/--games: must be positive." 
    sys.exit(1) 

답변

120

type을 사용하여 가능해야합니다. 당신은 아직도 당신이 결정하는 실제 방법을 정의해야합니다 :

def check_positive(value): 
    ivalue = int(value) 
    if ivalue <= 0: 
     raise argparse.ArgumentTypeError("%s is an invalid positive int value" % value) 
    return ivalue 

parser = argparse.ArgumentParser(...) 
parser.add_argument('foo', type=check_positive) 

이것은 기본적으로 argparsedocs에서 perfect_square 기능에서 단 개조 예입니다. 당신이 당신의 인수에 대한 분뿐만 아니라 예측 가능한 최대있는 경우

+1

함수는 여러 값을 가질 수 있습니까? 어떻게 작동합니까? – Tom

+0

'int' 로의 변환이 실패하면 여전히 읽을 수있는 출력이있을 것입니까? 아니면 수동으로 변환을 "시도"해야합니까? – NOhs

+2

@MrZ'error : argument foo : invalid check_positive value : 'foo = ''과 같은 것을 쓸 것입니다. 더 나은 에러 메시지로 예외를 다시 일으키는'try :'...'except ValueError :'를 단순히 추가하면됩니다. – Yuushi

3

빠른 더러운 방법은, 같은 조건/수표를 처리하기 위해 권장되는 옵션이 될 것입니다 범위

parser.add_argument('foo', type=int, choices=xrange(0, 1000)) 
+12

단점은 끔찍한 결과입니다. – jgritty

+3

_dirty_에 중점을 둡니다. –

+2

jgritty의 요점을보다 명확하게 이해하기 위해 choices = xrange (0,1000)는 --help를 사용할 때마다 또는 유효하지 않은 인수가 제공 될 때마다 1에서 999까지의 전체 정수 목록을 콘솔에 기록합니다. 대부분의 상황에서는 좋은 선택이 아닙니다. – biomiker

36

typechoices을 사용하는 것입니다 유시의 대답. 당신의 상한이 알려진 경우

특정 경우

, 당신은 또한 choices 매개 변수를 사용할 수 있습니다 :

parser.add_argument('foo', type=int, choices=xrange(5, 10)) 
+2

범위를 생성 한 다음 사이클을 통해 입력 내용의 유효성을 검사 할 때 상당히 비효율적이라고 상상해보십시오. 빠른'if'는 훨씬 빠릅니다. – TravisThomas

+2

@ trav1th 사실 그것은 있을지 모르지만 문서의 사용 예입니다. 또한, 유시의 대답이 바로 그 대답이라고 말했습니다. 옵션을 제공하는 것이 좋습니다. argparse의 경우 실행 당 한 번 발생하며 생성기 ('xrange')를 사용하며 추가 코드가 필요하지 않습니다. 그 절충안을 사용할 수 있습니다. 각 방법에 따라 결정할 수 있습니다. – aneroid

+9

벤 저자의 대답에 대한 jgritty의 점을 명확히 알기 위해 choices = xrange (0,1000)를 사용하면 --help를 사용할 때마다 1에서 999까지의 전체 정수 목록이 콘솔에 기록됩니다. 가 제공됩니다. 대부분의 상황에서는 좋은 선택이 아닙니다. – biomiker

2

간단한 대안을, argparse.ArgumentParser를 서브 클래 싱하기는 parse_args 방법 내부에서 유효성 검사를 시작하는 것입니다 특히 . 이 기술은 사용자 정의 호출만큼 시원하지 않을 수 있습니다

def parse_args(self, args=None, namespace=None): 
    """Parse and validate args.""" 
    namespace = super().parse_args(args, namespace) # super() works in Python 3 
    if namespace.games <= 0: 
     raise self.error('The number of games must be a positive integer.') 
    return namespace 

하지만, 작업을 수행합니다

같은 서브 클래스 내부

.


소개 ArgumentParser.error(message) :

This method prints a usage message including the message to the standard error and terminates the program with a status code of 2.


제공 : answer by jonatan