回答:
この回答は、optparse
どちらが古いバージョンのPythonに適しているかを示唆しています。Python 2.7以降でargparse
は、を置き換えoptparse
ます。詳細については、この回答を参照してください。
他の人が指摘したように、あなたはgetoptよりもoptparseを使うほうが良いです。getoptは、標準のgetopt(3)Cライブラリ関数のほぼ1対1のマッピングであり、非常に使いやすいものではありません。
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行のpython。
それをsample.pyに保存して、一度実行してください
python sample.py
そして一度
python sample.py --query myquery
さらに、optparseの拡張は非常に簡単です。私のプロジェクトの1つで、コマンドツリーにサブコマンドを簡単にネストできるようにするCommandクラスを作成しました。optparseを多用してコマンドをチェーン化します。これは数行で簡単に説明できるものではありませんが、メインクラスとそれを使用するクラスとオプションパーサーのリポジトリを自由に参照してください。
-mcProfile -o program.prof
、agrsを追加するだけでアプリケーション全体のプロファイルを作成できますが、agrparcerがこれらの引数をキャプチャしています。これらの引数を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.
これがドキュメントのサンプルコードです:
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
つまり、一言で言えば、それがどのように機能するかです。
2種類のオプションがあります。議論を受けている人や、まるでスイッチのような人。
sys.argv
char** argv
Cとほぼ同じです。Cと同様に、プログラムの名前である最初の要素をスキップし、引数のみを解析します。sys.argv[1:]
Getopt.getopt
引数で指定したルールに従って解析します。
"ho:v"
ここでは、短い引数について説明します-ONELETTER
。:
手段-o
1つの引数を受け入れます。
最後に["help", "output="]
、長い引数について説明します(--MORETHANONELETTER
)。=
後の出力は再びその出力は1つの引数を受け付けます。
結果はカップル(オプション、引数)のリストです
オプションが引数を受け入れない場合(--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など)で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
素晴らしいですし、完全に文書化コマンドラインスイッチと高度な機能のための正しい答えである、あなたは非常に簡単にハンドルに簡単位置引数に関数の引数のデフォルト値を使用することができます。
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
いくつかのデフォルト値が必要なだけの単純なスクリプトの場合、これで十分です。戻り値に型強制を含めることもできます。そうしないと、コマンドライン値はすべて文字列になります。
getoptよりoptparseの方が好きです。それは非常に宣言的です:あなたはそれにオプションの名前とそれらが持つべき効果(例えばbooleanフィールドの設定)を伝え、そしてあなたの仕様に従って入力された辞書をあなたに返します。
大規模なプロジェクトに最適な方法は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''
これはライブラリではなくメソッドで、私にとってはうまくいくようです。
ここでの目標は簡潔にすることです。各引数は1行で解析され、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()を使用すると、 'skip'はループをスキップして、フラグの解析を1つのライナーに抑えます。
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)