Pythonコマンドライン引数を解析するための最も簡単で、最も簡潔で、最も柔軟なメソッドまたはライブラリは何ですか?
15 に答える
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
、古い 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 を多用します。数行で簡単に説明できるものではありませんが、メイン クラス、それを使用するクラス、およびオプション パーサーのリポジトリを自由に参照してください。
ほぼ全員が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
つまり、これがどのように機能するかです。
2種類のオプションがあります。議論を受けている人、そしてスイッチのような人。
sys.argv
char** argv
Cの場合と同様に、プログラムの名前である最初の要素をスキップして、引数のみを解析します。sys.argv[1:]
Getopt.getopt
引数で指定したルールに従って解析します。
"ho:v"
ここで短い引数について説明します:-ONELETTER
。1つの引数を受け入れる:
手段。-o
最後に["help", "output="]
長い引数(--MORETHANONELETTER
)について説明します。after出力は=
、出力が1つの引数を受け入れることを意味します。
結果はカップルのリストです(オプション、引数)
--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 など) で 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()
大規模なプロジェクトには 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 の方が好きです。これは非常に宣言的です。オプションの名前とそれらが持つべき効果 (たとえば、ブール フィールドの設定) を指定すると、仕様に従って入力された辞書が返されます。
これは、ライブラリではなく、私にとってはうまくいくと思われる方法です。
ここでの目標は簡潔にすること、各引数を 1 行で解析すること、読みやすくするために args を並べること、コードがシンプルで特別なモジュール (os + sys のみ) に依存しないこと、不足している引数や不明な引数について適切に警告することです。 、単純な for/range() ループを使用し、python 2.x および 3.x で動作します
2 つのトグル フラグ (-d、-v) と、引数によって制御される 2 つの値 (-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() が使用されるときにループをスキップし、フラグの解析を 1 つのライナーに抑えます。
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''