답변:
이 답변은 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
5 줄의 파이썬으로 기본 사항을 보여줍니다.
sample.py에 저장하고 다음으로 한 번 실행하십시오.
python sample.py
그리고 한번
python sample.py --query myquery
그 외에도 optparse는 확장하기가 매우 쉽다는 것을 알게 될 것입니다. 내 프로젝트 중 하나에서 명령 트리에 하위 명령을 쉽게 중첩시킬 수있는 Command 클래스를 만들었습니다. optparse를 많이 사용하여 명령을 함께 연결합니다. 몇 줄로 쉽게 설명 할 수는 없지만 주 클래스의 저장소 와 클래스 및 옵션 파서를 사용하는 클래스를 자유롭게 탐색 하십시오.
-mcProfile -o program.prof
있지만 agrparcer는 args를 캡처하고 있습니다.이 args를 python exe에 전달하는 방법
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
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 개 라인 플러스 문서화 문자열 입니다 필수을하고 당신이 얻을 당신의 인수를 구문 분석하고 인수 객체에서 사용할 수 있습니다.
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
클릭을 선호합니다 . 옵션 관리를 추상화하고 "(...) 필요한만큼 적은 코드로 구성 가능한 방식으로 멋진 명령 줄 인터페이스를 만들 수 있습니다".
사용법 예는 다음과 같습니다.
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
부분은 빈 문자열입니다. 그런 다음 일반적으로이 목록을 반복하고 예제와 같이 옵션 이름을 테스트하려고합니다.
이것이 도움이 되었기를 바랍니다.
getopt
최신 버전의 Python에서 더 이상 사용되지 않으므로이 답변은 오래되었습니다.
getopt
더 이상 사용되지 않습니다… 그러나 문서에 따르면 C getopt()
함수에 익숙한 사용자에게 주로 제공되며 다른 사용자에게는 argparse
더 적은 코드를 작성하고 얻을 수있는 더 나은 솔루션 일 수 있습니다 더 나은 도움말 및 오류 메시지 "
사용 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를 getopt보다 선호합니다. 매우 선언적입니다. 옵션의 이름과 그 효과 (예 : 부울 필드 설정)를 알려주고 사양에 따라 채워진 사전을 알려줍니다.
더 큰 프로젝트에 가장 적합한 방법은 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
declarative_parser
. 물론, werkzeug와 함께 일하고 있다면을 유지하는 것이 좋습니다 werkzung.script
. 어쨌든, 나는 그런 접근 방식의 열렬한 팬입니다.
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)
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''
여기 라이브러리가 아닌 방법이 있습니다.
여기서 목표는 간결하고, 각 인수는 한 줄로 구문 분석되고, 인수는 가독성을 위해 정렬되며, 코드는 간단하며 특수 모듈 (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 ()의 목표는 누락 된 데이터를 확인하는 동안 다음 인수를 반환하는 것이며 NextArg ()가 사용될 때 'skip'은 루프를 건너 뛰어 플래그 구문 분석을 한 라이너로 유지합니다.
필요한 위치 인수와 선택적 인수를 허용하도록 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)