sys.argv [x]が定義されているかどうかの確認


回答:


64

結局、try, exceptとテストの違いlen(sys.argv)はそれほど重要ではありません。どちらも、に比べて少しハックですargparse

しかし、これは私には起こります-一種の低予算のargparseとして:

arg_names = ['command', 'x', 'y', 'operation', 'option']
args = dict(zip(arg_names, sys.argv))

これを使用してnamedtuple、デフォルトの値を持つを生成することもできますNone-すべて4行です!

Arg_list = collections.namedtuple('Arg_list', arg_names)
args = Arg_list(*(args.get(arg, None) for arg in arg_names))

に慣れていない場合はnamedtuple、オブジェクトのように機能するタプルにすぎないため、tup.attribute構文ではなくtup[0]構文を使用してその値にアクセスできます。

したがって、最初の行は、のnamedtuple各値の値を持つ新しいタイプを作成しますarg_names。2行目はargsディクショナリから値を渡し、get指定された引数名がディクショナリに関連付けられた値を持たない場合にデフォルト値を返すために使用します。


私はPythonをますます好きにしています。そのような答えともちろんスタックオーバーフローのおかげです。残念ながら、最後の2行の説明はありません。初心者にとっては素晴らしいと思います。
Goujon 2017年

2
大好きです!この問題について私が見た最も簡単な解決策は簡単です。他の人のために:1)「コマンド」の最初の引数としてそれぞれの時間を通過し、2)あなたは引数[0]などで結果を呼び出すことができます。これは、と私(初心者くさい)にすぐに明らかではなかった
マット・D

これは確かに素晴らしいですが、長さをテストする上で何がハッキーですか
colorlace

1
@timwiz argparseを使用する場合と比較して話しているだけです。それでも、最近では、古いスクリプトに戻ってargparseを使用していないことに気づくたびに、自分を蹴っています。
sendle

116

の長さを確認してくださいsys.argv

if len(sys.argv) > 1:
    blah = sys.argv[1]
else:
    blah = 'blah'

あなたが提案した例外ベースのアプローチを好む人もいます(例:)が、try: blah = sys.argv[1]; except IndexError: blah = 'blah'あまり適切に「スケーリング」されないため(たとえば、2つまたは3つの引数を受け入れたい場合)、私はそれほど好きではありません。エラーを隠す可能性blah = foo(sys.argv[1])があります(たとえば、を使用したがをfoo(...)発生させたIndexError場合、それIndexErrorは無視されます)。


1
ただし、アトミックである限り、について心配する必要はありませんtry, except。節fooまでの議論を待ってくださいelse
センダーレ2011年

3
また、スケーリングについて検討した後は、に移りましょうargparse
センダーレ2011年

1
argparseで+1。私はargparse.pyすべてのコマンドラインプロジェクトに参加しています。
David Wolever、

2
@senderle:確かに、あなたがそれについて勤勉であれば、それで結構です。しかし、私の経験では、ほとんどのプログラマーは勤勉ではなく、すべてのロジックをtry節に入れています…ですから、難しくはない(そして、IMOは少しきれいです)ので、長さをチェックするだけです(また、フロー制御の例外を使用することをあなたに怒鳴る)。
David Wolever

2
@David、ええ、私はあなたの主張を理解しています。私は少しtryお詫び申し上げます、認めなければなりません。それは時々、自分の意図をif陳述よりも明確に表現していると感じています。
センダーレ2011年

22

リストに載っていないもう1つの方法は、事前にセンチネル値を設定することです。このメソッドはPythonの遅延評価を利用します。この場合、常にelseステートメントを提供する必要はありません。例:

startingpoint = 'blah'
if len(sys.argv) >= 2:
  startingpoint = sys.argv[1]

または、構文CRAZYを行う場合は、Pythonの三項演算子を使用できます。

startingpoint = sys.argv[1] if len(sys.argv) >= 2 else 'blah'

1
三項演算子の答えは、私の目には最も美しいです。私がここに座っているのは、私が管理しているソフトウェアの一部が、Python 2.4に関連付けられており、それを持たないという事実を静かに罵っています。
リチャードバレル2012

11

私はこれを使用します-失敗することはありません:

startingpoint = 'blah'
if sys.argv[1:]:
   startingpoint = sys.argv[1]

定義されているかどうかを確認することではありません。存在する場合は定義に似ていますが、同じではありません。私もその方法を使用してフォールバック変数を評価しましたが、現在の質問に対する回答ではありません。
m3nda 2015

@ erm3nda startingpoint例から変数を削除できますが、問題はフォールバック変数を割り当てることなので、同じようにしました。
anatly techtonik 2015

1
削除すると、定義されていない変数に関するエラーが発生します。私はもう一度質問を読みました、そして彼が期待しているのは、変数の置換です:)だから大丈夫です。もしそうなら、その短い道のアドバイスをありがとうsys.argv[1:]:。これは位置引数で機能しますが、countは機能しません。
m3nda 2015

10

これは普通のPythonリストです。このためにキャッチする例外はIndexErrorですが、代わりに長さを確認することをお勧めします。

if len(sys.argv) >= 2:
  startingpoint = sys.argv[1]
else:
  startingpoint = 'blah'

2

マップの組み込み機能を使用するソリューション!

arg_names = ['command' ,'operation', 'parameter']
args = map(None, arg_names, sys.argv)
args = {k:v for (k,v) in args}

次に、次のようにパラメーターを呼び出すだけです。

if args['operation'] == "division":
    if not args['parameter']:
        ...
    if args['parameter'] == "euclidian":
        ...

1

argv [1]の値をargvに追加し、argv [1]が入力した文字列と等しくないかどうかを確認できます。例:

from sys import argv
argv.append('SomeString')
if argv[1]!="SomeString":
            print(argv[1])

私に反対票を投じた人たちのために、間違いを明確にしないためにあなたに恥を。
Hassan Abdul-Kareem 2016年

それはハックだからだと思います。誰かが引数としてSomeStringを渡した場合はどうなりますか?あなたが受け入れることができるならばそれをどのように使うかは1から5の引数を言うことができますか?
pbogut

ユーザーが引数を提供しない場合に備えてデフォルト値を設定するためのクールな(しかしまだハック)。追加してargv [1]を使用します。
Felizett 2017年

1

オリジネーターがやろうとしていたことにかなり近い。これが私が使用する関数です:

def get_arg(index):
    try:
        sys.argv[index]
    except IndexError:
        return ''
    else:
        return sys.argv[index]

したがって、使用法は次のようになります。

if __name__ == "__main__":
    banner(get_arg(1),get_arg(2))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.