명령 줄 인수를 읽고 처리하는 방법?


623

5
docopt를 사용하십시오 ( stackoverflow.com/a/14790373/116891 의 @ralbatross의 답변 참조 ). 나는 다른 모든 방법을 시도했지만 실제로 docopt는 앞으로 사용할 유일한 것입니다.
Pat

2
최선의 방법은 하나도 없다고 생각합니다. argparse는 표준적이고 기능적입니다. docopt는 매우 우아하지만 표준 라이브러리에는 없습니다. 매우 쉬운 경량 사용을 위해 함수 기본값이 쉼표 라인 인수 기본값을 처리 하도록 할 수 있습니다 .
Simon Hibbs

답변:


456

표준 라이브러리의 표준 솔루션은 argparse( docs )입니다.

예를 들면 다음과 같습니다.

from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument("-f", "--file", dest="filename",
                    help="write report to FILE", metavar="FILE")
parser.add_argument("-q", "--quiet",
                    action="store_false", dest="verbose", default=True,
                    help="don't print status messages to stdout")

args = parser.parse_args()

argparse 지원 (다른 것들 중에서) :

  • 어떤 순서로든 여러 옵션.
  • 짧고 긴 옵션.
  • 기본값.
  • 사용 도움말 메시지 생성

27
예, 이것들이 최고입니다. 그것들은 표준 라이브러리의 일부이므로 사용 가능하고 사용하기 쉽다는 것을 확신 할 수 있습니다. optparse는 특히 강력하고 쉽습니다.
Barry Wark

4
optparse는 최고 중 하나입니다. getopt는 오래되었으며 실제로는 더 이상 사용되지 않는 것으로 간주되어야합니다.
jemfinch

12
이 시점에서 (2011 년 12 월), argparse는 optparse보다 더 나은 옵션으로 간주됩니다. 맞습니까?
oob

54
Python Documentation은 optparse 대신 argparse 를 사용하도록 제안합니다 .
earthmeLon

7
optparse더 이상 사용되지 않기 때문에 질문의 질문자는 더 이상 스택 오버플로의 구성원이 아니며 이것은 눈에 잘 띄는 질문에 대한 대답입니다 argparse. 대신 stdlib를 사용하도록 예제 코드를 완전히 다시 작성하십시오 .
wim

548
import sys

print("\n".join(sys.argv))

sys.argv 명령 행에서 스크립트에 전달 된 모든 인수를 포함하는 목록입니다.

원래,

import sys
print(sys.argv[1:])

83
정말 간단한 것들을 위해, 이것은 당신이 아마 사용하고 싶지만 sys.argv[1:](스크립트 이름은 피할 것입니다), 갈 길이 입니다.
Xiong Chiamiov

128

이러한 이유 때문에 더 나은 argparse에 대한 복음화를 돌아 다니는 것 .. 본질적으로 :

(링크에서 복사)

  • argparse 모듈은 위치 및 선택적 인수를 처리 할 수있는 반면 optparse는 선택적 인수 만 처리 할 수 ​​있습니다

  • argparse는 명령 행 인터페이스의 모양에 대해 독단적이지 않습니다. 필수 옵션 인 -file 또는 / file과 같은 옵션이 지원됩니다. Optparse는 실용성보다 순도를 선호하여 이러한 기능을 지원하지 않습니다.

  • argparse는 인수에서 결정된 명령 줄 사용법을 비롯하여보다 유용한 정보 메시지를 생성하고 위치 및 선택적 인수에 대한 도움말 메시지를 생성합니다. optparse 모듈은 자체 사용 문자열을 작성해야하며 위치 인수에 대한 도움말을 표시 할 방법이 없습니다.

  • argparse는 다양한 수의 명령 줄 인수를 사용하는 동작을 지원하는 반면, optparse는 정확한 수의 인수 (예 : 1, 2 또는 3)를 미리 알고 있어야합니다.

  • argparse는 하위 명령으로 디스패치하는 파서를 지원하는 반면 optparse allow_interspersed_args는 파서 디스패치를 ​​수동으로 설정 하고 수행해야합니다.

그리고 내 개인적인 마음에 드는 것 :

  • argparse를 사용하면 add_argument() 간단한 callables 로 type 및 action 매개 변수를 지정할 수 있지만 optparse는 해킹 클래스 속성과 같은 해킹 클래스 속성이 필요 STORE_ACTIONS하거나 CHECK_METHODS적절한 인수 검사가 필요합니다

27
이것은 지금 2.7의 표준 파이썬의 일부 3.2입니다 :)
jpswain

"선택적 인수"란 무엇입니까? 당신은 그들이 optparse에 있다고 말합니다. 나는 그것들이 제공 될 수도 있고 제공되지 않을 수도있는 주장이라고 생각했지만, "optparse는 정확한 수의 주장을 미리 알고 있어야한다"고 말하면서 옵토 스에 있다고 말했다. "선택적 인수"에 대한 귀하의 정의가 내가 생각한 것과 다르거 나 귀하의 답변이 그 자체와 일치하지 않습니다.
ArtOfWarfare

1
간단한 설명 : argparse 문서도 미묘하고 복잡합니다. "명령 줄 인수를 어떻게 단일 값으로 취하고 어떻게 그 값에 액세스합니까?"에 대한 간단한 대답을 얻을 수 없습니다. </ gripe>
osman

2
@osman argparse에 관한이 부드러운 튜토리얼 이 도움이 될 것입니다.
lifebalance

2
이 문맥에서 @ArtOfWarfare "선택적 인수"는 아마도 -f또는 같은 옵션과 같은 인수로 지정된 인수를 의미 --foo하는 반면, "정확한 수의 인수를 미리 알 수 있음"은 선행 옵션 플래그없이 주어진 위치 인수를 의미합니다.
mtraceur

67

또한이 argparse다음 stdlib 모듈 (다음 stdlib의에서 "impovement" optparse모듈). argparse 소개의 예 :

# script.py
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'integers', metavar='int', type=int, choices=range(10),
         nargs='+', help='an integer in the range 0..9')
    parser.add_argument(
        '--sum', dest='accumulate', action='store_const', const=sum,
        default=max, help='sum the integers (default: find the max)')

    args = parser.parse_args()
    print(args.accumulate(args.integers))

용법:

$ script.py 1 2 3 4
4

$ script.py --sum 1 2 3 4
10

1
그냥 복사하여 붙여 넣기
blitu12345

3
내 답변을 게시 할 때 @ blitu12345 어떤 식 으로든 argparse를 언급하는 다른 답변은 없었습니다. 모듈 자체는 stdlib에 없었습니다 ¶ 문서의 코드 예제에 대해 무엇을 가지고 있습니까? 모듈 작성자가 제공 한 예제 대신 자신의 예제를 생각해 내야하는 이유는 무엇입니까? 그리고 나는 링크 전용 답변을 좋아하지 않습니다 (나는 혼자가 아닙니다).
jfs

1
여기에 오는 사람들은 이미 문서에 무엇이 있는지 알고 있으며 주제에 대한 추가 정리를 위해 여기에있을 것입니다. 나의 경우이지만 실제로 여기에서 찾은 것은 원본 문서의 사본과 붙여 넣기입니다.
blitu12345

2
"여기 오는 사람들은 이미 문서에 아이디어 뭐죠 있었다"- 나는 매우 그 assumtion을 의심한다. 어쩐지.
sjas

49

한 가지 방법은을 사용하는 것 sys.argv입니다. 그러면 스크립트 이름이 첫 번째 인수로 전달되고 다른 모든 매개 변수가 전달됩니다.

import sys

for arg in sys.argv:
    print arg

49

docopt의 라이브러리는 정말 매끄러운입니다. 앱의 사용 문자열에서 인수 dict를 작성합니다.

예를 들어 docopt readme에서 :

"""Naval Fate.

Usage:
  naval_fate.py ship new <name>...
  naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
  naval_fate.py ship shoot <x> <y>
  naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
  naval_fate.py (-h | --help)
  naval_fate.py --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine.

"""
from docopt import docopt


if __name__ == '__main__':
    arguments = docopt(__doc__, version='Naval Fate 2.0')
    print(arguments)

4
이것은 내가 가장 좋아하는 방법이되었습니다. 문자열 구문 분석이므로 취하기가 쉽지만 한곳 에서 부서지기 쉽고 try.docopt.org 에서 논리를 미리 볼 수 있습니다 . 선택적이고 상호 배타적 인 주장은 정말 우아한 방식으로 이루어집니다.
gvoysey

4
naval_fate.py에 대한 나머지 코드를 보려고 필사적입니다.
John Lawrence Aspden

48

빠르고 유연하지 않은 무언가가 필요한 경우

main.py :

import sys

first_name = sys.argv[1]
last_name = sys.argv[2]
print("Hello " + first_name + " " + last_name)

그런 다음 실행 python main.py James Smith

다음과 같은 출력을 생성합니다.

제임스 스미스 안녕하세요


보다 사실적인 사용이 될 python main.py "James Smith"하는 박았 James Smithsys.argv[1]와 생산 IndexError이 존재하지 않는를 사용하려고하면 sys.argv[2]. 인용 동작은 파이썬을 실행하는 플랫폼과 쉘에 따라 다소 다릅니다.
tripleee

10
내 사용법이 덜 현실적인 것에 동의하지 않습니다. 사람들이 이름과 성을 여러 개 가질 수있는 사업체에서 스크립트를 실행하려면 프로그램에서 사람의 정확한 성과 이름을 알아야합니까? 제임스 스미스가 조셉을 이름이나 성으로 추가했다면, 조셉이 이름이나 성으로 구분할 수 있다면 어떻게해야 python main.py "James Joseph Smith"할까요? 범위를 벗어난 인덱스에 관심이있는 경우 제공된 인수 수에 대한 검사를 추가 할 수 있습니다. 현실적이지 않은지, 내 예는 여러 인수를 처리하는 방법을 보여줍니다.
켄트먼트 캐스 퍼슨

1
다른 모든 답변은 달 착륙 임무를 꾸미기위한 것입니다. 나는 단순히을 사용하고 gmail-trash-msg.py MessageID있습니다. 이 답변은 테스트 MessageID매개 변수가 전달되었습니다 sys.argv[1].
WinEunuuchs2Unix

26
#set default args as -h , if no args:
if len(sys.argv) == 1: sys.argv[1:] = ["-h"]

19

나는 optparse를 직접 사용하지만 Simon Willison이 최근 소개 한 optfunc 라이브러리 를 사용하는 방향과 같습니다 . 다음과 같이 작동합니다.

"함수 정의 (인수 및 기본값 포함)를 조사하고이를 사용하여 명령 행 인수 구문 분석기를 구성합니다."

예를 들어이 함수 정의는 다음과 같습니다.

def geocode(s, api_key='', geocoder='google', list_geocoders=False):

이 optparse 도움말 텍스트로 바뀝니다.

    Options:
      -h, --help            show this help message and exit
      -l, --list-geocoders
      -a API_KEY, --api-key=API_KEY
      -g GEOCODER, --geocoder=GEOCODER

8

나는 stdlib에서 getopt를 좋아한다.

try:
    opts, args = getopt.getopt(sys.argv[1:], 'h', ['help'])
except getopt.GetoptError, err: 
    usage(err)

for opt, arg in opts:
    if opt in ('-h', '--help'): 
        usage()

if len(args) != 1:
    usage("specify thing...")

최근에 나는 이것을 덜 장황하게 만들기 위해 비슷한 것을 포장 해왔다 (예 : "-h"를 암시 적으로 만들기).


8

Pocoo의 클릭 은보다 직관적이고 보일러 플레이트가 덜 필요하며 최소한 argparse만큼 강력합니다.

내가 지금까지 만난 유일한 약점은 페이지를 돕기 위해 많은 사용자 정의를 수행 할 수 없지만 일반적으로 요구 사항은 아니며 docopt 는 명확한 선택처럼 보입니다.


7

optparse 를 볼 수 있듯이 "optparse 모듈은 더 이상 사용되지 않으며 더 이상 개발되지 않으며 argparse 모듈로 계속 개발됩니다 ."


5
import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                   help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                   const=sum, default=max,
                   help='sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))

Assuming the Python code above is saved into a file called prog.py
$ python prog.py -h

Ref-link: https://docs.python.org/3.3/library/argparse.html

4

커맨드 라인 인수를보다 쉽게 ​​처리하기 위해 작성한 작은 Python 모듈에 관심이있을 수 있습니다 (오픈 소스 및 무료) -Commando


1
Commando라는 다른 명령 줄 구문 분석 모듈 ( github.com/lakshmivyas/commando) 이 이미 있습니다 . 데코레이터를 사용하여 argparse를 래핑합니다.
Roberto Bonvallet

1
파이썬과 휠 재발 명
Derek

4

나는 docopt 를 다른 것들에 대한 간단한 대안으로 보는 것이 좋습니다 .

docopt는 모든 것을 직접 구현할 필요없이 --help 사용법 메시지를 구문 분석하여 작동하는 새로운 프로젝트입니다. 사용 메시지를 POSIX 형식으로 입력하면됩니다.


4

또 다른 옵션은 argh 입니다. argparse를 기반으로하며 다음과 같은 내용을 작성할 수 있습니다.

import argh

# declaring:

def echo(text):
    "Returns given word as is."
    return text

def greet(name, greeting='Hello'):
    "Greets the user with given name. The greeting is customizable."
    return greeting + ', ' + name

# assembling:

parser = argh.ArghParser()
parser.add_commands([echo, greet])

# dispatching:

if __name__ == '__main__':
    parser.dispatch()

자동으로 도움말 등을 생성하며 데코레이터를 사용하여 arg-parsing 작동 방식에 대한 추가 지침을 제공 할 수 있습니다.


이것이 가장 좋은 해결책입니다. 사용하는 argh것이 다른 라이브러리 나 사용하는 것보다 쉽습니다 sys.
Juanjo Salvador 2016

나는 마음에 argh들었지만 원한다면 하위 명령으로 명령을하지 않는 시나리오에는 적합하지 않습니다.
tripleee

1
@tripleee YMMV, 그러나 이것이 라이브러리 자체보다 문서에서 더 많은 결함이라는 것을 알았습니다. def frobnicate_spleches(...)스크립트가 수행하는 모든 기능을 정의한 다음 if __name__ == '__main__': argh.dispatch_command(frobnicate_spleches)파일 끝에서 수행하는 기능을 정의하는 것이 완벽하게 실현 가능해 보입니다 .
Circular-ruin

0

내 솔루션은 entrypoint2 입니다. 예:

from entrypoint2 import entrypoint
@entrypoint
def add(file, quiet=True): 
    ''' This function writes report.

    :param file: write report to FILE
    :param quiet: don't print status messages to stdout
    '''
    print file,quiet

도움말 텍스트 :

usage: report.py [-h] [-q] [--debug] file

This function writes report.

positional arguments:
  file         write report to FILE

optional arguments:
  -h, --help   show this help message and exit
  -q, --quiet  don't print status messages to stdout
  --debug      set logging level to DEBUG
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.