パラメータが指定されていない場合、スクリプトはデモモードを開始する必要があります。私はこれを試しました:
args = parser.parse_args()
if len(args) == 0:
run_demo()
else:
# evaluate args
これは、リストがないので、*** TypeError: object of type 'Namespace' has no len()
を与えargs
ます。
どうすれば私が望むことを達成できますか?
パラメータが指定されていない場合、スクリプトはデモモードを開始する必要があります。私はこれを試しました:
args = parser.parse_args()
if len(args) == 0:
run_demo()
else:
# evaluate args
これは、リストがないので、*** TypeError: object of type 'Namespace' has no len()
を与えargs
ます。
どうすれば私が望むことを達成できますか?
コマンドに引数が与えられていないことを検出することが目標である場合、これを行うargparse
のは間違ったアプローチです(Benがうまく指摘しているように)。
シンプルに考えてください!:-)argparseは過疎化しないと思いますsys.argv
。したがって、if not len(sys.argv) > 1
ユーザーは引数を指定していません。
argparseを使用すると、仕様と解析対象のコマンドラインに基づいて、パーサーに追加した引数で言及されているすべての変数を(名前空間オブジェクト内で)設定できます。デフォルトを設定した場合、それらの変数はコマンドラインに表示されていなければそのデフォルト値になり、名前空間オブジェクトに存在しなくなります。また、デフォルトを指定しない場合は、暗黙のデフォルトとして。がありますNone
。したがって、名前空間オブジェクトの長さをチェックすることは、どのように実行しても、引数が解析されたかどうかをチェックする方法としては意味がありません。常に同じ長さである必要があります。
None
代わりに、デフォルトのない引数がたくさんあり、それらのいずれかが非値に設定されているかどうかを確認したい場合は、それを実行してください。Martijnの回答に示されているように、リスト内包表記と関数を使用して、呼び出しvars
から名前のリストを複製することなく、それらをループすることができます。add_argument
一部の引数にデフォルト値がある場合は少し注意が必要です。さらに、コマンドラインで明示的に指定できるデフォルト値がある場合(たとえば、デフォルトが0の数値引数では、ユーザーからデフォルトを区別できなくなります)。 0を提供)。その場合、引数が何であるかを知らなくても常に機能する一般的な解決策があるかどうかはわかりません。
本当に引数番号が必要な場合(何らかの理由で)。私はこのコードが非常に役立つことを発見しました(しかし、それがどれほど最適化されているかはわかりません、そして私はそれについてのコメントをいただければ幸いです)。
args = parser.parse_args()
print( len( vars(args) ) )
このバージョンでは、-xxパラメーターのみがカウントされ、渡された追加の値はカウントされません。
すべて(渡される値も)が必要な場合は、len(sys.argv)
前述のように使用します。
argparseは使用しないでください。代わりに。を使用してsys.argv
ください。argparse
名前空間を作成するため、スクリプトを呼び出したときに使用した引数に応じて、値とともに常に「dict」が提供されます。
これが私が過去にしたことです:
args = parser.parse_args()
if len(sys.argv) == 1:
parser.print_help()
sys.exit()
return args
私はそれが古いスレッドであることを知っていますが、他の人にも役立つかもしれないより直接的な解決策を見つけました:
引数が渡されたかどうかを確認できます。
if any(vars(args).values()):
# evaluate args
または、引数が渡されていない場合(not
演算子に注意してください):
if not any(vars(args).values()):
run_demo()
説明:
parse_args()
すべての引数名とそれに関連する値を含む「名前空間」オブジェクトを返します。例:Namespace(arg1='myfile.txt', arg2='some/path/to/some/folder')
引数が渡されていない場合parse_args()
は、同じオブジェクトを返しますが、すべての値が。として返されNone
ます。例:Namespace(arg1=None, arg2=None)
ただし、このオブジェクトは反復可能ではないため、値にアクセスできるように、を使用vars()
してに変換する必要があります。dict
最後に、dict
手元にあるので、ですべての値を取得しlist
、.values()
組み込みany()
関数を使用して、値のいずれかが。でないかどうかを確認できますNone
。明確にするために:そうでない値が1つもない場合、または(ドキュメントを参照してください)フィードしたリストにある場合にany()
戻ります。False
None
False
0
それが役に立てば幸い。
完全を期すためにYoursを拡張するために、次の例を想定します。
#!/usr/bin/env python3
import argparse
...
def main():
parser = argparse.ArgumentParser()
parser.add_argument('input', nargs='?' action='store')
parser.add_argument('-l', '--length', type=int, action='store')
parser.add_argument('-v', '--verbose', action='store_true')
args = parser.parse_args()
if (args.input == None and args.length == None):
parser.print_help()
else:
print(args)
if __name__ == '__main__':
main()
この例では、@Benによって言及されている名前空間オブジェクトはですargs
。parser.add_argument
変数の文字列から作成されます。args.input
またはargs.length
またはからアクセスできますargs.verbose
。これを確認するには、実行するprint(args)
と次のようになります。
Namespace(input=None, length=None, verbose=False)
verboseはに設定されているためTrue
、存在し、入力と長さが単なる変数であり、インスタンス化する必要はありません(引数は提供されません)。
group = parser.add_mutually_exclusive_group()
また、2つの属性を同時に提供できないことを確認したい場合にも役立ちます。
詳細については、以下を参照してください。
2dvisioの概念を拡張して、ゼロ以外またはNoneの引数をカウントしました。
vm_opts = parser.parse_args()
v = vars(vm_opts)
n_args = sum([ 1 for a in v.values( ) if a])
すべての入力で同じである単一のタイプの引数が渡されたかどうかを確認する最も単純なケースでは、とを使用して3つのステップでそれを行うことができargparse
ますnumpy
。
import argparse
import numpy as np
args = parser.parse_args()
# namespace to dictionary
args_dict = vars(args)
# unpack values from dictionary, pass to array
values = np.array([*args_dict.values()])
# Check if the defaults have changed
args_indices = np.where(values != default)[0]
# Did we pass any arguments?
if len(values) == len(args_indices):
print("No arguments were passed")
長さは、引数が渡されたかどうかを確認するためのプロキシとして使用されます。どちらが渡されたかを知りたい場合は、キーを解凍して、変更されたインデックスを確認します。
np.array()
より複雑な場合の論理演算子を受け入れます。