programing

명령줄 인수를 해석하는 가장 좋은 방법은 무엇입니까?

newsource 2022. 11. 16. 21:18

명령줄 인수를 해석하는 가장 좋은 방법은 무엇입니까?

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

은 '그러다'를 암시합니다.optparse파이썬2.일 경우 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라는 Atribute에 인수를 저장하며 지정하지 않으면 기본값이 됩니다.또한 옵션에서 바로 help 인수(-h/--help와 함께 실행할 때 사용)를 선언하는 것도 자기 문서화되어 있습니다.

통상, 다음의 방법으로 인수를 해석합니다.

options, args = parser.parse_args()

기본적으로는 스크립트에 전달된 표준 인수(sys.argv[1:])가 해석됩니다.

옵션들.그러면 쿼리가 스크립트에 전달된 값으로 설정됩니다.

파서를 작성하려면 다음 작업을 수행합니다.

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

기본을 보여주는 파이썬 5줄.

sample.py에 저장한 후 를 사용하여 한 번 실행합니다.

python sample.py

그리고 한번은

python sample.py --query myquery

그 밖에도 optparse는 매우 쉽게 확장할 수 있습니다.프로젝트 중 하나에서 명령 트리에 하위 명령을 쉽게 중첩할 수 있는 명령 클래스를 만들었습니다.optparse를 많이 사용하여 명령어를 결합합니다.간단하게 몇 줄 설명할 수 있는 은 아니지만, 메인 클래스나 그것을 사용하는 클래스, 옵션 파서저장소 내를 자유롭게 탐색할 수 있습니다.

docopt 사용

2012년 이후 docopt라고 하는 인수 해석에 매우 쉽고 강력하며 매우 뛰어난 모듈이 등장했습니다.다음으로 매뉴얼에서 인용한 예를 제시하겠습니다.

"""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줄과 doc 문자열이 필수적이며 인수를 구문 분석하여 인수 오브젝트에서 사용할 수 있습니다.

python-fire 사용

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 현재 argparse는 표준 라이브러리의 일부이며 optparse는 권장되지 않습니다.

클릭을 선호합니다.관리 옵션을 추상화하고 "(...) 필요한 최소한의 코드만으로 구성 가능한 방식으로 아름다운 명령줄 인터페이스를 만들 수 있습니다."

다음은 사용 예를 제시하겠습니다.

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 서 、 : 、 : 、 : 、 : 、 : 、 : : : : : : : : : the the the the the the만 합니다.sys.argv[1:]

Getopt.getopt인수에서 지정한 규칙에 따라 해석합니다.

"ho:v"에서는 짧은합니다.-ONELETTER . 。: -o는 하나의 인수를 받아들입니다.

★★★★★★★★★★★★★★★★★.["help", "output="] 긴 「긴 인수」)에 설명합니다.--MORETHANONELETTER=은 다시 한 번 것을 합니다.after output은 1개의 인수를 받아들인다는 입니다.

결과는 커플 리스트(옵션, 인수)입니다.

이 인수를 않는 : " " " " " ) 。--help( ★★★★★★★★★★★★★★★」arg는 빈입니다.part는 빈 문자열입니다.그런 다음 보통 이 목록에서 루프하여 예시와 같이 옵션 이름을 테스트합니다.

도움이 되셨길 바랍니다.

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를 사용하는 이유는 무엇입니까?

Lightweight 명령줄 인수 기본값

일일 ~일도 although although although although 。argparse는 훌륭하며 완전히 문서화된 명령줄 스위치 및 확장 기능에 대한 올바른 답변입니다.function 인수 defaults를 사용하면 간단한 위치 인수를 쉽게 처리할 수 있습니다.

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

기본값이 필요한 간단한 스크립트의 경우 이 정도면 충분합니다.반환값에 강제 유형을 포함하거나 명령줄 값이 모두 문자열이 될 수도 있습니다.

만약을 위해 Win32(2K, XP 등)에서 Unicode 인수를 취득할 필요가 있는 경우에 도움이 될 수 있습니다.


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 코드는 실제 구현 코드보다 길 수 있습니다!

가장 일반적인 인수 구문 분석 옵션에서 찾을 수 있는 문제는 파라미터가 미미한 수준일 경우 파라미터를 문서화하는 코드가 불균형적으로 커지기 때문에 이점을 얻을 수 있다는 것입니다.

인수 해석 씬(내 생각에)의 비교적 새로운 접근자는 플라시입니다.

몇 확인된 하여 argparse를 .main() type "time":

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)

나는 getopt보다 optparse를 선호한다.이것은 매우 선언적입니다.옵션의 이름과 그 효과(예를 들어 부울 필드 설정)를 말하면 사양에 따라 채워진 사전이 반환됩니다.

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

대규모 프로젝트에는 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

consoleargs는 여기서 언급할 필요가 있습니다.그것은 매우 사용하기 쉽다.확인해 주세요.

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''

여기 라이브러리가 아닌 방법이 있는데, 저한테는 효과가 있을 것 같아요.

여기서의 목적은 간결하고 각 인수가 한 줄로 해석되며 args는 가독성을 위해 정렬됩니다.코드는 단순하고 특별한 모듈(os + sys만)에 의존하지 않으며 누락 또는 알 수 없는 인수에 대해 적절히 경고하고 단순한 for/range() 루프를 사용하여 python 2.x 및 3.x에서 동작합니다.

2개의 토글플래그(-d, -v)와 인수(-i xxx 및 -o xxx)에 의해 제어되는2개의 값을 나타냅니다.

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()의 목적은 누락된 데이터를 체크하면서 다음 인수를 반환하는 것입니다.NextArg()를 사용하면 루프를 건너뛰어 플래그를 1개의 라이너로 해석할 수 있습니다.

나는 Erco의 접근방식을 확장하여 필요한 위치 인수와 선택적 인수를 허용했다.이들은 -d, -v. 인수 앞에 와야 합니다.

PosArg(i) 및 OptArg(i, 기본값)를 사용하여 positional 인수와 optArg(i, default) 인수를 각각 가져올 수 있습니다.옵션 인수가 발견되면 옵션 검색 시작 위치(예: -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) 

언급URL : https://stackoverflow.com/questions/20063/whats-the-best-way-to-parse-command-line-arguments