문제

무엇입니까? 가장 쉬운, 가장 간결한, 그리고 대부분의 유연한 Python 명령줄 인수를 구문 분석하기 위한 메서드 또는 라이브러리?

도움이 되었습니까?

해결책

이 답변은 제안합니다 optparse 이는 이전 Python 버전에 적합합니다.Python 2.7 이상의 경우, argparse 대체하다 optparse.보다 이 답변 자세한 내용은.

다른 사람들이 지적했듯이 getopt보다 optparse를 사용하는 것이 더 좋습니다.getopt는 표준 getopt(3) C 라이브러리 함수의 일대일 매핑이며 사용하기가 쉽지 않습니다.

optparse는 조금 더 장황하지만 구조가 훨씬 좋고 나중에 확장하기가 더 간단합니다.

다음은 파서에 옵션을 추가하는 일반적인 줄입니다.

parser.add_option('-q', '--query',
            action="store", dest="query",
            help="query string", default="spam")

그것은 그 자체로 거의 말해줍니다.처리 시 -q 또는 --query를 옵션으로 허용하고 인수를 query라는 속성에 저장하며 지정하지 않으면 기본값을 갖습니다.또한 옵션과 함께 도움말 인수(-h/--help와 함께 실행할 때 사용됨)를 바로 선언한다는 점에서 자체 문서화됩니다.

일반적으로 다음을 사용하여 인수를 구문 분석합니다.

options, args = parser.parse_args()

이는 기본적으로 스크립트(sys.argv[1:])에 전달된 표준 인수를 구문 분석합니다.

그러면 options.query가 스크립트에 전달된 값으로 설정됩니다.

다음을 수행하여 파서를 생성합니다.

parser = optparse.OptionParser()

이것이 필요한 모든 기본 사항입니다.다음은 이를 보여주는 완전한 Python 스크립트입니다.

import optparse

parser = optparse.OptionParser()

parser.add_option('-q', '--query',
    action="store", dest="query",
    help="query string", default="spam")

options, args = parser.parse_args()

print 'Query string:', options.query

기본 사항을 보여주는 Python 5줄.

Sample.py에 저장하고 다음과 같이 한 번 실행해 보세요.

python sample.py

그리고 한 번은

python sample.py --query myquery

그 외에도 optparse는 확장이 매우 쉽다는 것을 알게 될 것입니다.내 프로젝트 중 하나에서 명령 트리에 하위 명령을 쉽게 중첩할 수 있는 Command 클래스를 만들었습니다.명령을 함께 연결하기 위해 optparse를 많이 사용합니다.몇 줄로 쉽게 설명할 수 있는 내용은 아니지만, 내 저장소를 둘러보세요 메인 클래스 뿐만 아니라 이를 사용하는 클래스와 옵션 파서

다른 팁

다른 답변에서는 다음과 같이 언급합니다. argparse 새로운 Python을 선택하는 방법이지만 사용 예를 제공하지는 마세요.완전성을 위해 argparse 사용 방법에 대한 간략한 요약은 다음과 같습니다.

1) 초기화

import argparse

# Instantiate the parser
parser = argparse.ArgumentParser(description='Optional app description')

2) 인수 추가

# Required positional argument
parser.add_argument('pos_arg', type=int,
                    help='A required integer positional argument')

# Optional positional argument
parser.add_argument('opt_pos_arg', type=int, nargs='?',
                    help='An optional integer positional argument')

# Optional argument
parser.add_argument('--opt_arg', type=int,
                    help='An optional integer argument')

# Switch
parser.add_argument('--switch', action='store_true',
                    help='A boolean switch')

3) 파싱

args = parser.parse_args()

4) 접근

print("Argument values:")
print(args.pos_arg)
print(args.opt_pos_arg)
print(args.opt_arg)
print(args.switch)

5) 값 확인

if args.pos_arg > 10:
    parser.error("pos_arg cannot be larger than 10")

용법

올바른 사용:

$ ./app 1 2 --opt_arg 3 --switch

Argument values:
1
2
3
True

잘못된 인수:

$ ./app foo 2 --opt_arg 3 --switch
usage: convert [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
app: error: argument pos_arg: invalid int value: 'foo'

$ ./app 11 2 --opt_arg 3
Argument values:
11
2
3
False
usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]
convert: error: pos_arg cannot be larger than 10

전체 도움말:

$ ./app -h

usage: app [-h] [--opt_arg OPT_ARG] [--switch] pos_arg [opt_pos_arg]

Optional app description

positional arguments:
  pos_arg            A required integer positional argument
  opt_pos_arg        An optional integer positional argument

optional arguments:
  -h, --help         show this help message and exit
  --opt_arg OPT_ARG  An optional integer argument
  --switch           A boolean switch

docopt 사용

2012년부터 Python은 매우 쉽고 강력하며 실제로 시원한 인수 구문 분석을 위한 모듈이 호출되었습니다. 문서화하다.Python 2.6~3.5에서 작동하며 설치가 필요하지 않습니다(복사만 하면 됩니다).다음은 문서에서 가져온 예입니다.

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

그래서 이것이다:2줄의 코드와 문서 문자열 ~이다 필수이며 인수 개체에서 인수를 구문 분석하고 사용할 수 있습니다.내가 멋지다고 말했지, 그렇지? ;-)

파이썬 파이어 사용하기

2017년부터 파이썬 파이어 당신과 함께 코드에 CLI 인터페이스를 제공할 수 있는 또 다른 멋진 모듈이 있습니다. 인수 분석.다음은 문서의 간단한 예입니다(이 작은 프로그램은 함수를 노출합니다. double 명령줄에):

import fire

class Calculator(object):

  def double(self, number):
    return 2 * number

if __name__ == '__main__':
  fire.Fire(Calculator)

명령줄에서 다음을 실행할 수 있습니다.

> calculator.py double 10
20
> calculator.py double --number=15
30

정말 멋지지 않나요?

새로운 힙웨이는 argparse ~을 위한 이것들 원인.argparse > optparse > getopt

업데이트: py2.7부터 인수 표준 라이브러리의 일부이며 선택 분석 더 이상 사용되지 않습니다.

나는 선호한다 딸깍 하는 소리.관리 옵션을 추상화하고 "(...) 필요한 만큼 적은 코드를 사용하여 구성 가능한 방식으로 아름다운 명령줄 인터페이스를 생성"할 수 있습니다.

사용 예는 다음과 같습니다.

import click

@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo('Hello %s!' % name)

if __name__ == '__main__':
    hello()

또한 다음과 같이 적절한 형식의 도움말 페이지를 자동으로 생성합니다.

$ python hello.py --help
Usage: hello.py [OPTIONS]

  Simple program that greets NAME for a total of COUNT times.

Options:
  --count INTEGER  Number of greetings.
  --name TEXT      The person to greet.
  --help           Show this message and exit.

거의 다들 사용하고 계시더라구요 getopt

문서의 예제 코드는 다음과 같습니다.

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        if o in ("-o", "--output"):
            output = a

한마디로 작동 방식은 다음과 같습니다.

두 가지 유형의 옵션이 있습니다.논쟁을받는 사람들과 스위치와 같은 사람들.

sys.argv 거의 당신이에요 char** argv C에서C와 마찬가지로 프로그램 이름인 첫 번째 요소를 건너뛰고 인수만 구문 분석합니다. sys.argv[1:]

Getopt.getopt 인수에 제공한 규칙에 따라 구문 분석합니다.

"ho:v" 여기에 짧은 인수가 설명되어 있습니다. -ONELETTER.그만큼 : 의미하는 것은 -o 하나의 주장을 받아들입니다.

마지막으로 ["help", "output="] 긴 인수를 설명합니다( --MORETHANONELETTER ).그만큼 = 출력 후 다시 한 번 출력이 하나의 인수를 허용함을 의미합니다.

결과는 커플(옵션,인수) 목록입니다.

옵션이 어떤 인수도 허용하지 않는 경우(예: --help 여기서) arg 부분은 빈 문자열입니다.그런 다음 일반적으로 이 목록을 반복하고 예제에서와 같이 옵션 이름을 테스트하려고 합니다.

이것이 당신에게 도움이 되었기를 바랍니다.

사용 optparse 표준 라이브러리와 함께 제공됩니다.예를 들어:

#!/usr/bin/env python
import optparse

def main():
  p = optparse.OptionParser()
  p.add_option('--person', '-p', default="world")
  options, arguments = p.parse_args()
  print 'Hello %s' % options.person

if __name__ == '__main__':
  main()

원천: Python을 사용하여 UNIX 명령줄 도구 만들기

그러나 Python 2.7부터 optparse는 더 이상 사용되지 않습니다. 다음을 참조하세요. optparse 대신 argparse를 사용하는 이유는 무엇입니까?

필요한 경우를 대비해 필요한 경우 도움이 될 수 있습니다. 붙잡다 Win32(2K, XP 등)의 유니코드 인수:


from ctypes import *

def wmain(argc, argv):
    print argc
    for i in argv:
        print i
    return 0

def startup():
    size = c_int()
    ptr = windll.shell32.CommandLineToArgvW(windll.kernel32.GetCommandLineW(), byref(size))
    ref = c_wchar_p * size.value
    raw = ref.from_address(ptr)
    args = [arg for arg in raw]
    windll.kernel32.LocalFree(ptr)
    exit(wmain(len(args), args))
startup()

경량 명령줄 인수 기본값

하지만 argparse 훌륭하고 완전히 문서화된 명령줄 스위치와 고급 기능에 대한 정답입니다. 함수 인수 기본값을 사용하여 간단한 위치 인수를 매우 간단하게 처리할 수 있습니다.

import sys

def get_args(name='default', first='a', second=2):
    return first, int(second)

first, second = get_args(*sys.argv)
print first, second

'name' 인수는 스크립트 이름을 캡처하며 사용되지 않습니다.테스트 출력은 다음과 같습니다.

> ./test.py
a 2
> ./test.py A
A 2
> ./test.py A 20
A 20

몇 가지 기본값만 원하는 간단한 스크립트의 경우 이 정도면 충분하다고 생각합니다.반환 값에 일부 유형 강제를 포함할 수도 있습니다. 그렇지 않으면 명령줄 값이 모두 문자열이 됩니다.

대규모 프로젝트를 위한 가장 좋은 방법은 optparse라고 생각합니다. 하지만 쉬운 방법을 찾고 있다면 아마도 http://werkzeug.pocoo.org/documentation/script 당신을 위한 것입니다.

from werkzeug import script

# actions go here
def action_foo(name=""):
    """action foo does foo"""
    pass

def action_bar(id=0, title="default title"):
    """action bar does bar"""
    pass

if __name__ == '__main__':
    script.run()

따라서 기본적으로 모든 기능 Action_*는 명령 줄에 노출되며 멋진 도움말 메시지가 무료로 생성됩니다.

python foo.py 
usage: foo.py <action> [<options>]
       foo.py --help

actions:
  bar:
    action bar does bar

    --id                          integer   0
    --title                       string    default title

  foo:
    action foo does foo

    --name                        string

나는 getopt보다 optparse를 선호합니다.매우 선언적입니다.옵션의 이름과 그 옵션이 가져야 하는 효과(예: 부울 필드 설정)를 알려주면 사양에 따라 채워진 사전을 돌려줍니다.

http://docs.python.org/lib/module-optparse.html

콘솔 인수 여기서 언급할 가치가 있습니다.사용하기가 매우 쉽습니다.확인 해봐:

from consoleargs import command

@command
def main(url, name=None):
  """
  :param url: Remote URL 
  :param name: File name
  """
  print """Downloading url '%r' into file '%r'""" % (url, name)

if __name__ == '__main__':
  main()

이제 콘솔에서:

% python demo.py --help
Usage: demo.py URL [OPTIONS]

URL:    Remote URL 

Options:
    --name -n   File name

% python demo.py http://www.google.com/
Downloading url ''http://www.google.com/'' into file 'None'

% python demo.py http://www.google.com/ --name=index.html
Downloading url ''http://www.google.com/'' into file ''index.html''

Argparse 코드는 실제 구현 코드보다 길 수 있습니다!

가장 널리 사용되는 인수 구문 분석 옵션에서 제가 발견한 문제는 매개 변수가 적당하지 않은 경우 매개 변수를 문서화하는 코드가 매개 변수가 제공하는 이점에 비해 불균형적으로 커진다는 것입니다.

인수 분석 장면에 상대적으로 새로 온 사람은 (내 생각에) 장소.

argparse와 일부 인정된 절충안을 제공하지만 인라인 문서를 사용하고 간단히 래핑합니다. main() 유형 기능 기능:

def main(excel_file_path: "Path to input training file.",
     excel_sheet_name:"Name of the excel sheet containing training data including columns 'Label' and 'Description'.",
     existing_model_path: "Path to an existing model to refine."=None,
     batch_size_start: "The smallest size of any minibatch."=10.,
     batch_size_stop:  "The largest size of any minibatch."=250.,
     batch_size_step:  "The step for increase in minibatch size."=1.002,
     batch_test_steps: "Flag.  If True, show minibatch steps."=False):
"Train a Spacy (http://spacy.io/) text classification model with gold document and label data until the model nears convergence (LOSS < 0.5)."

    pass # Implementation code goes here!

if __name__ == '__main__':
    import plac; plac.call(main)

나에게 맞는 라이브러리가 아닌 방법이 있습니다.

여기서의 목표는 간결하게 하는 것입니다. 각 인수는 한 줄로 구문 분석되고, args는 가독성을 위해 정렬되고, 코드는 간단하고 특수 모듈(os + sys만)에 의존하지 않으며 누락되거나 알 수 없는 인수에 대해 우아하게 경고합니다. , 간단한 for/range() 루프를 사용하고 Python 2.x 및 3.x에서 작동합니다.

두 개의 토글 플래그(-d, -v)와 인수로 제어되는 두 개의 값(-i xxx 및 -o xxx)이 표시됩니다.

import os,sys

def HelpAndExit():
    print("<<your help output goes here>>")
    sys.exit(1)

def Fatal(msg):
    sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
    sys.exit(1)

def NextArg(i):
    '''Return the next command line argument (if there is one)'''
    if ((i+1) >= len(sys.argv)):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return(1, sys.argv[i+1])

### MAIN
if __name__=='__main__':

    verbose = 0
    debug   = 0
    infile  = "infile"
    outfile = "outfile"

    # Parse command line
    skip = 0
    for i in range(1, len(sys.argv)):
        if not skip:
            if   sys.argv[i][:2] == "-d": debug ^= 1
            elif sys.argv[i][:2] == "-v": verbose ^= 1
            elif sys.argv[i][:2] == "-i": (skip,infile)  = NextArg(i)
            elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
            elif sys.argv[i][:2] == "-h": HelpAndExit()
            elif sys.argv[i][:1] == "-":  Fatal("'%s' unknown argument" % sys.argv[i])
            else:                         Fatal("'%s' unexpected" % sys.argv[i])
        else: skip = 0

    print("%d,%d,%s,%s" % (debug,verbose,infile,outfile))

NextArg()의 목표는 누락된 데이터를 확인하는 동안 다음 인수를 반환하는 것이며 'skip'은 NextArg()가 사용될 때 루프를 건너뛰어 플래그 구문 분석을 하나의 라이너로 유지합니다.

나는 필수 위치 인수와 선택적 인수를 허용하도록 Erco의 접근 방식을 확장했습니다.이는 -d, -v 등보다 앞에 와야 합니다.인수.

위치 및 선택적 인수는 각각 PosArg(i) 및 OptArg(i, 기본값)을 사용하여 검색할 수 있습니다.선택적 인수가 발견되면 옵션 검색 시작 위치(예:-i) '예기치 않은' 치명적인 결과를 피하기 위해 1 앞으로 이동합니다.

import os,sys


def HelpAndExit():
    print("<<your help output goes here>>")
    sys.exit(1)

def Fatal(msg):
    sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg))
    sys.exit(1)

def NextArg(i):
    '''Return the next command line argument (if there is one)'''
    if ((i+1) >= len(sys.argv)):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return(1, sys.argv[i+1])

def PosArg(i):
    '''Return positional argument'''
    if i >= len(sys.argv):
        Fatal("'%s' expected an argument" % sys.argv[i])
    return sys.argv[i]

def OptArg(i, default):
    '''Return optional argument (if there is one)'''
    if i >= len(sys.argv):
        Fatal("'%s' expected an argument" % sys.argv[i])
    if sys.argv[i][:1] != '-':
        return True, sys.argv[i]
    else:
        return False, default


### MAIN
if __name__=='__main__':

    verbose = 0
    debug   = 0
    infile  = "infile"
    outfile = "outfile"
    options_start = 3

    # --- Parse two positional parameters ---
    n1 = int(PosArg(1))
    n2 = int(PosArg(2))

    # --- Parse an optional parameters ---
    present, a3 = OptArg(3,50)
    n3 = int(a3)
    options_start += int(present)

    # --- Parse rest of command line ---
    skip = 0
    for i in range(options_start, len(sys.argv)):
        if not skip:
            if   sys.argv[i][:2] == "-d": debug ^= 1
            elif sys.argv[i][:2] == "-v": verbose ^= 1
            elif sys.argv[i][:2] == "-i": (skip,infile)  = NextArg(i)
            elif sys.argv[i][:2] == "-o": (skip,outfile) = NextArg(i)
            elif sys.argv[i][:2] == "-h": HelpAndExit()
            elif sys.argv[i][:1] == "-":  Fatal("'%s' unknown argument" % sys.argv[i])
            else:                         Fatal("'%s' unexpected" % sys.argv[i])
        else: skip = 0

    print("Number 1 = %d" % n1)
    print("Number 2 = %d" % n2)
    print("Number 3 = %d" % n3)
    print("Debug    = %d" % debug)
    print("verbose  = %d" % verbose)
    print("infile   = %s" % infile)
    print("outfile  = %s" % outfile) 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top