コマンドライン引数の読み取り/処理方法は?


623

5
docoptを使用します(stackoverflow.com/a/14790373/116891の @ralbatrossの回答を参照してください)。私は他の方法も試しましたが、実際には、docoptだけが今後使用する予定です。
2013年

2
最善の方法は1つだけとは思いません。argparseは標準で機能豊富です。docoptは非常にエレガントですが、標準ライブラリにはありません。非常に簡単で軽量な使用のために、関数のデフォルト値にコマンドライン引数のデフォルトを処理させることができます
Simon Hibbs 2017

回答:


456

標準ライブラリの標準的な解決策はargparsedocs)です:

次に例を示します。

from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument("-f", "--file", dest="filename",
                    help="write report to FILE", metavar="FILE")
parser.add_argument("-q", "--quiet",
                    action="store_false", dest="verbose", default=True,
                    help="don't print status messages to stdout")

args = parser.parse_args()

argparse サポート(とりわけ):

  • 複数のオプションを任意の順序で。
  • 短いオプションと長いオプション。
  • デフォルト値。
  • 使用法ヘルプメッセージの生成。

27
はい、これらは最高です。それらは標準ライブラリの一部であるため、確実に使用可能で使いやすいものになります。特にoptparseは強力で簡単です。
Barry Wark、

4
optparseは最高の1つです。getoptは古く、本当に非推奨と見なされるべきです。
jemfinch 2010

12
この時点(2011年12月)では、argparseはoptparseよりも優れたオプションと見なされていますよね?
oob

54
Pythonドキュメントでは、optparseではなくargparseの使用を推奨しています。
earthmeLon、2012年

7
optparseは非推奨になっているため、質問の質問者はスタックオーバーフローのメンバーではなくなりました。これは、非常に目立つ質問に対する承認された回答argparseです。代わりにstdlibを使用するようにサンプルコードを完全に書き直すことを検討してください。
ウィム

548
import sys

print("\n".join(sys.argv))

sys.argv コマンドラインでスクリプトに渡されるすべての引数を含むリストです。

基本的に、

import sys
print(sys.argv[1:])

83
本当に使いたいだけなのに、これだけで十分ですsys.argv[1:](スクリプト名は避けてください)。
Xiong Chiamiov

128

argparseの伝道を回るだけですが、これらの理由により本質的には優れてます。

(リンクからコピー)

  • argparseモジュールは位置引数とオプション引数を処理できますが、optparseはオプション引数のみを処理できます

  • argparseは、コマンドラインインターフェイスがどのように見えるべきかについて独断的ではありません--fileや/ fileのようなオプションは、必要なオプションと同様にサポートされています。Optparseはこれらの機能のサポートを拒否し、実用性よりも純粋さを優先します

  • argparseは、引数から決定されたコマンドラインの使用法や、位置引数とオプション引数の両方のヘルプメッセージを含む、より有益な使用法メッセージを生成します。optparseモジュールはあなた自身の使用法の文字列を書くことを要求し、位置引数のヘルプを表示する方法がありません。

  • argparseは可変数のコマンドライン引数を消費するアクションをサポートしますが、optparseは引数の正確な数(1、2、または3など)を事前に知っている必要があります

  • argparseはサブコマンドにディスパッチするパーサーをサポートしていますが、optparseはallow_interspersed_argsパーサーディスパッチを手動で設定および実行する必要があります

そして私の個人的なお気に入り:

  • argparseするタイプとアクションのパラメータができますadd_argument() optparseは同様にクラス属性をハッキングが必要ですが、簡単な呼び出し可能オブジェクトで指定する STORE_ACTIONSか、CHECK_METHODS適切な引数チェックを取得するには

27
これは現在、2.7および3.2の時点で標準Pythonの一部です:)
jpswain

「オプションの引数」とは何ですか?あなたは彼らがoptparseにいると言います。それらは提供されてもされなくてもよい引数であると思いましたが、「optparseは引数の正確な数が事前にわかっている必要がある」と言っている間、それらはoptparseにいるとあなたは言った。したがって、「オプションの引数」の定義が私が思っていたものと異なるか、またはあなたの答えがそれ自体と矛盾しています。
ArtOfWarfare 2014

1
ただ不満:argparseのドキュメントもめちゃくちゃ、めちゃくちゃ複雑です。「コマンドライン引数に単一の値をどのように取り込むのか、およびその値にどのようにアクセスするのか」という単純な答えは得られません。</
gripe

2
@osman argparseに関するこの穏やかなチュートリアルは役立つかもしれません...
ライフバランス

2
@ArtOfWarfareこのコンテキストでの「オプションの引数」は、おそらく-fやなどのオプションのような引数で指定された引数を意味しますが--foo、「正確な数の引数は事前にわかっている」は、おそらく先行するオプションフラグなしで与えられた位置引数を意味します。
mtraceur

67

ありargparseSTDLIBモジュール(STDLIBさんの「impovement」optparseモジュール)。argparseの紹介の例:

# script.py
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'integers', metavar='int', type=int, choices=range(10),
         nargs='+', help='an integer in the range 0..9')
    parser.add_argument(
        '--sum', dest='accumulate', action='store_const', const=sum,
        default=max, help='sum the integers (default: find the max)')

    args = parser.parse_args()
    print(args.accumulate(args.integers))

使用法:

$ script.py 1 2 3 4
4

$ script.py --sum 1 2 3 4
10

1
単なるコピーと貼り付け
blitu12345

3
@ blitu12345私の回答が公開された時点では、argparseに言及している回答は他にありませんでした。モジュール自体はstdlibにありませんでした¶ドキュメントのコード例に対して何がありますか?モジュールの作成者が提供した例ではなく、独自の例を考え出す必要があるのはなぜだと思いますか?また、リンクのみの回答は好きではありません(私は一人ではありません)。
jfs '20 / 06/20

1
ここに来る人々はすでにドキュメントに何が入っているか考えていましたが、トピックに関するさらなるクリアランスのためだけにここにあります。同じことが私のケースでしたが、私が実際にここで見つけたのは元のドキュメントからのコピーと貼り付けです。
blitu12345

2
「ここに来る人々はすでにドキュメントに何が入っているか考えていました」-私はその仮定を非常に疑っています。何とかして。
sjas

49

これを行う1つの方法は、を使用することですsys.argv。これにより、最初の引数としてスクリプト名と、それに渡される他のすべてのパラメーターが出力されます。

import sys

for arg in sys.argv:
    print arg

49

docoptのライブラリは本当に滑りやすいです。アプリの使用法文字列から引数dictを構築します。

たとえば、docopt readmeから:

"""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)

4
これは急速に私のお気に入りの方法になりました。これは文字列の解析であるため、一種の脆弱なものですが、すべて1か所で脆弱であり、try.docopt.orgでロジックをプレビューできます。オプションで相互に排他的な引数は、非常にエレガントな方法で行われます。
gvoysey 2016年

4
naval_fate.pyの残りのコードを見るのは必死です
John Lawrence Aspden

48

高速で柔軟性のないものが必要な場合

main.py:

import sys

first_name = sys.argv[1]
last_name = sys.argv[2]
print("Hello " + first_name + " " + last_name)

次に実行します python main.py James Smith

次の出力を生成します。

こんにちはJames Smith


より現実的な使用法は、存在しないを使用しようとしたときにpython main.py "James Smith"を挿入James Smithsys.argv[1]て生成するIndexErrorことですsys.argv[2]。引用動作は、Pythonを実行するプラットフォームとシェルによって多少異なります。
tripleee 2017

10
私の使用法があまり現実的でないことに同意しません。人々が複数の姓名を持つことができるビジネスでスクリプトを実行するために、プログラムが人物の正確な姓名を知っている必要があるとしましょう。ジェームス・スミスが追加の姓または名としてジョセフを持っている場合、あなただけが行う場合、ジョセフが追加の姓または名であるかどうかをどのように区別しpython main.py "James Joseph Smith"ますか?範囲外のインデックスに関心がある場合は、提供された引数の数のチェックを追加できます。あまり現実的ではないにせよ、私の例は複数の引数を処理する方法を示しています。
Kent Munthe Caspersen、2018年

1
他のすべての答えは、月着陸ミッションを計画するためのものです。私は単にを使用していgmail-trash-msg.py MessageIDます。この答えは簡単です。テストMessageIDパラメータが渡されましたsys.argv[1]
WinEunuuchs2Unix

26
#set default args as -h , if no args:
if len(sys.argv) == 1: sys.argv[1:] = ["-h"]

19

私は自分自身でoptparseを使用していますが、Simon Willisonが最近導入したoptfuncライブラリーで取っている方向が本当に好きです。それはによって働きます:

「関数の定義(引数とそのデフォルト値を含む)をイントロスペクトし、それを使用してコマンドライン引数パーサーを構築します。」

したがって、たとえば、次の関数定義は:

def geocode(s, api_key='', geocoder='google', list_geocoders=False):

このoptparseヘルプテキストに変わります:

    Options:
      -h, --help            show this help message and exit
      -l, --list-geocoders
      -a API_KEY, --api-key=API_KEY
      -g GEOCODER, --geocoder=GEOCODER

8

stdlibのgetoptが好きです。例:

try:
    opts, args = getopt.getopt(sys.argv[1:], 'h', ['help'])
except getopt.GetoptError, err: 
    usage(err)

for opt, arg in opts:
    if opt in ('-h', '--help'): 
        usage()

if len(args) != 1:
    usage("specify thing...")

最近、私はこれに似たものをラップして、物事の冗長性を減らしています(たとえば、「-h」を暗黙的にする)。


8

Pocooのクリックはより直感的で、必要なボイラープレートが少なく、少なくともargparseと同じくらい強力です。

私がこれまでに遭遇した唯一の弱点は、ページをヘルプするために多くのカスタマイズを行うことができないことですが、それは通常は要件ではなく、docoptは明確な選択のようです。



5
import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                   help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                   const=sum, default=max,
                   help='sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))

Assuming the Python code above is saved into a file called prog.py
$ python prog.py -h

Ref-link: https://docs.python.org/3.3/library/argparse.html

4

コマンドライン引数の処理をさらに簡単にするために私が書いた小さなPythonモジュールに興味があるかもしれません(オープンソースで自由に使用できます)-Commando


1
Commandoという名前の別のコマンドライン解析モジュールがすでにあります:github.com/lakshmivyas/commando。デコレータを使用してargparseをラップします。
Roberto Bonvallet、2011

1
pythonとwheelの再発明
Derek

4

私はこれらの他の単純な代替としてdocoptを見ることをお勧めします。

docoptは、すべてを自分で実装するように要求するのではなく、-help使用法メッセージを解析することによって機能する新しいプロジェクトです。使用法メッセージをPOSIX形式で入力するだけです。


4

さらに別のオプションはarghです。これはargparseに基づいて構築されており、次のようなものを記述できます。

import argh

# declaring:

def echo(text):
    "Returns given word as is."
    return text

def greet(name, greeting='Hello'):
    "Greets the user with given name. The greeting is customizable."
    return greeting + ', ' + name

# assembling:

parser = argh.ArghParser()
parser.add_commands([echo, greet])

# dispatching:

if __name__ == '__main__':
    parser.dispatch()

ヘルプなどを自動的に生成し、デコレータを使用して、引数の解析がどのように機能するかについて追加のガイダンスを提供できます。


これが最良の解決策です。を使用するarghと、他のライブラリやを使用するよりも簡単ですsys
Juanjo Salvador 2017

私は好きになりたかったのですarghが、サブコマンド付きのコマンドを持たないことが最大の目的であるシナリオには特に適していません。
tripleee 2017

1
@tripleee YMMVですが、これはライブラリ自体よりもドキュメントの欠陥の方が多いことがわかりました。def frobnicate_spleches(...)スクリプトが実行することをすべて実行する関数を定義しif __name__ == '__main__': argh.dispatch_command(frobnicate_spleches)、ファイルの最後で実行することは、完全に実行可能であるように思われます。
円形遺跡、

0

私の解決策はentrypoint2です。例:

from entrypoint2 import entrypoint
@entrypoint
def add(file, quiet=True): 
    ''' This function writes report.

    :param file: write report to FILE
    :param quiet: don't print status messages to stdout
    '''
    print file,quiet

ヘルプテキスト:

usage: report.py [-h] [-q] [--debug] file

This function writes report.

positional arguments:
  file         write report to FILE

optional arguments:
  -h, --help   show this help message and exit
  -q, --quiet  don't print status messages to stdout
  --debug      set logging level to DEBUG
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.