복붙노트

[PYTHON] 명령 줄 인수를 구문 분석하는 가장 좋은 방법은 무엇입니까?

PYTHON

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

파이썬 커맨드 라인 인자를 파싱하기위한 가장 쉽고, 간결하고, 가장 유연한 메소드 나 라이브러리는 무엇입니까?

해결법

  1. ==============================

    1.이 대답은 이전 Python 버전에 적합한 optparse를 제안합니다. Python 2.7 이상에서는 argparse가 optparse를 대체합니다. 자세한 내용은이 답변을 참조하십시오.

    이 대답은 이전 Python 버전에 적합한 optparse를 제안합니다. 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()
    

    이것들은 당신이 필요로하는 모든 기본 사항입니다. 다음은이를 보여주는 완벽한 파이썬 스크립트입니다 :

    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는 매우 쉽게 확장 할 수 있습니다. 내 프로젝트 중 하나에서 Command 클래스의 하위 명령을 쉽게 중첩 할 수있는 Command 클래스를 만들었습니다. 그것은 명령을 함께 연결하기 위해 optparse를 많이 사용합니다. 몇 줄에서 쉽게 설명 할 수있는 것은 아니지만 기본 클래스에 대한 저장소와 옵션 파서를 사용하는 클래스를 자유롭게 탐색 할 수 있습니다.

  2. ==============================

    2.다른 대답은 argparse가 새로운 Python을 사용하는 방법이지만 사용 예제를 제공하지 않는다는 것을 언급합니다. 완전성을 위해 다음은 argparse 사용법에 대한 간단한 요약입니다.

    다른 대답은 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
    
  3. ==============================

    3.2012 년 이래로 Python에는 docopt라는 인수 파싱을위한 매우 쉽고 강력하며 멋진 모듈이 있습니다. Python 2.6에서 3.5까지 작동하며 설치가 필요하지 않습니다. 다음은 문서에서 가져온 예제입니다.

    2012 년 이래로 Python에는 docopt라는 인수 파싱을위한 매우 쉽고 강력하며 멋진 모듈이 있습니다. 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 행의 코드와 필수적인 doc 문자열입니다. 여러분은 여러분의 인수를 파싱하여 인수 객체에서 사용할 수 있습니다. 나는 그것이 멋지다는 것을 말했다, 나는 그렇지 않았다 ;-)

    2017 년 이래로 python-fire에는 인자가없는 구문 분석을 수행하면서 코드에 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
    

    굉장하지 않아?

  4. ==============================

    4.새로운 엉덩이 방법은 이러한 이유로 argparse입니다. argparse> optparse> getopt

    새로운 엉덩이 방법은 이러한 이유로 argparse입니다. argparse> optparse> getopt

    update : py2.7부터 argparse는 표준 라이브러리의 일부이고 optparse는 더 이상 사용되지 않습니다.

  5. ==============================

    5.꽤 많은 사람들이 getopt를 사용하고 있습니다.

    꽤 많은 사람들이 getopt를 사용하고 있습니다.

    다음은 doc에 대한 예제 코드입니다.

    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는 C에서와 마찬가지로 char * argv입니다. C와 마찬가지로 프로그램의 이름 인 첫 번째 요소를 건너 뛰고 인수 만 구문 분석합니다. sys.argv [1 :]

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

    "ho : v"는 짧은 논증을 설명합니다 : -ONELETTER. :는 -o가 하나의 인수를 허용한다는 것을 의미합니다.

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

    결과는 부부 목록 (옵션, 인수)

    옵션이 (--help here와 같은) 인수를 허용하지 않으면 arg 부분은 빈 문자열입니다. 그런 다음 일반적으로이 목록을 반복하고 예제 에서처럼 옵션 이름을 테스트하려고합니다.

    이게 당신을 도왔 으면 좋겠어요.

  6. ==============================

    6.표준 라이브러리와 함께 제공되는 optparse를 사용하십시오. 예 :

    표준 라이브러리와 함께 제공되는 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 명령 행 도구 만들기

    그러나 파이썬 2.7에서 optparse는 더 이상 사용되지 않습니다. optparse 대신 argparse를 사용하는 이유는 무엇입니까?

  7. ==============================

    7.나는 Click을 선호한다. 관리 옵션을 추상화하고 필요에 따라 간단한 코드로 "(...) 구성 가능한 방식으로 아름다운 명령 행 인터페이스를 만들 수 있습니다."

    나는 Click을 선호한다. 관리 옵션을 추상화하고 필요에 따라 간단한 코드로 "(...) 구성 가능한 방식으로 아름다운 명령 행 인터페이스를 만들 수 있습니다."

    예제 사용법은 다음과 같습니다.

    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.
    
  8. ==============================

    8.필요하다면 Win32 (2K, XP 등)에서 유니 코드 인수를 얻어야하는 경우에 도움이 될 수 있습니다.

    필요하다면 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()
    
  9. ==============================

    9.나는 더 큰 프로젝트를위한 최선의 방법은 optparse다고 생각한다. 그러나 쉬운 방법을 찾고 있다면 아마도 http://werkzeug.pocoo.org/documentation/script가 당신에게 도움이 될 것이다.

    나는 더 큰 프로젝트를위한 최선의 방법은 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
    
  10. ==============================

    10.경량 명령 줄 인수 기본값

    경량 명령 줄 인수 기본값

    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
    

    방금 일부 기본값을 원할 경우 간단한 스크립트를 위해이 방법이 충분하다는 것을 알았습니다. 반환 값에 형식 강제 변환을 포함 시키거나 명령 줄 값을 모두 문자열로 포함시킬 수도 있습니다.

  11. ==============================

    11.나는 getopt에 optparse를 선호한다. 매우 선언적입니다 : 옵션의 이름과 그 효과 (예 : 부울 필드 설정)를 지정하고 사양에 따라 채워지는 사전을 다시 전달합니다.

    나는 getopt에 optparse를 선호한다. 매우 선언적입니다 : 옵션의 이름과 그 효과 (예 : 부울 필드 설정)를 지정하고 사양에 따라 채워지는 사전을 다시 전달합니다.

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

  12. ==============================

    12.consoleargs 여기 언급해야합니다. 그것은 매우 사용하기 쉽습니다. 확인 해봐:

    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''
    
  13. ==============================

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

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

    그게 가장 인기있는 인수 구문 분석 옵션으로 찾을 수있는 문제는 매개 변수가 겸손한 경우이를 문서화하는 코드가 제공하는 이점에 비해 불균형 적으로 커진다는 것입니다.

    인자 파싱 장면 (나는 생각한다)에 상대적으로 새로운 것은 plac이다.

    그것은 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)
    
  14. ==============================

    14.방법은 라이브러리가 아니라 저를 위해 작동하는 것 같습니다.

    방법은 라이브러리가 아니라 저를 위해 작동하는 것 같습니다.

    목표는 간결하고 각 인수는 한 줄로 분석하고 args는 가독성을 위해 정렬하며 코드는 단순하고 특별한 모듈 (os + sys 만)에 의존하지 않고 누락되거나 알 수없는 인수에 대해 경고합니다 , / range () 루프를 사용하고 파이썬 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 ()의 목적은 누락 된 데이터를 확인하는 동안 다음 인수를 반환하고 NextArg ()가 사용될 때 '건너 뛰기'가 루프를 건너 뛰고 플래그 구문 분석을 한 개의 라이너로 유지하는 것입니다.

  15. ==============================

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

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

    PosArg (i) 및 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) 
    
  16. from https://stackoverflow.com/questions/20063/whats-the-best-way-to-parse-command-line-arguments by cc-by-sa and MIT license