65

パラメータが指定されていない場合、スクリプトはデモモードを開始する必要があります。私はこれを試しました:

args = parser.parse_args()
if len(args) == 0:
    run_demo()
else:
    # evaluate args

これは、リストがないので、*** TypeError: object of type 'Namespace' has no len()を与えargsます。

どうすれば私が望むことを達成できますか?

4

8 に答える 8

109

コマンドに引数が与えられていないことを検出することが目標である場合、これを行うargparseのは間違ったアプローチです(Benがうまく指摘しているように)。

シンプルに考えてください!:-)argparseは過疎化しないと思いますsys.argv。したがって、if not len(sys.argv) > 1ユーザーは引数を指定していません。

于 2012-05-22T09:44:37.580 に答える
20

argparseを使用すると、仕様と解析対象のコマンドラインに基づいて、パーサーに追加した引数で言及されているすべての変数を(名前空間オブジェクト内で)設定できます。デフォルトを設定した場合、それらの変数はコマンドラインに表示されていなければそのデフォルト値になり、名前空間オブジェクトに存在しなくなります。また、デフォルトを指定しない場合は、暗黙のデフォルトとして。がありますNone。したがって、名前空間オブジェクトの長さをチェックすることは、どのように実行しても、引数が解析されたかどうかをチェックする方法としては意味がありません。常に同じ長さである必要があります。

None代わりに、デフォルトのない引数がたくさんあり、それらのいずれかが非値に設定されているかどうかを確認したい場合は、それを実行してください。Martijnの回答に示されているように、リスト内包表記と関数を使用して、呼び出しvarsから名前のリストを複製することなく、それらをループすることができます。add_argument

一部の引数にデフォルト値がある場合は少し注意が必要です。さらに、コマンドラインで明示的に指定できるデフォルト値がある場合(たとえば、デフォルトが0の数値引数では、ユーザーからデフォルトを区別できなくなります)。 0を提供)。その場合、引数が何であるかを知らなくても常に機能する一般的な解決策があるかどうかはわかりません。

于 2012-05-22T09:30:56.177 に答える
11

本当に引数番号が必要な場合(何らかの理由で)。私はこのコードが非常に役立つことを発見しました(しかし、それがどれほど最適化されているかはわかりません、そして私はそれについてのコメントをいただければ幸いです)。

args = parser.parse_args()
print( len( vars(args) ) )

このバージョンでは、-xxパラメーターのみがカウントされ、渡された追加の値はカウントされません。

すべて(渡される値も)が必要な場合は、len(sys.argv)前述のように使用します。

于 2013-08-21T15:25:13.760 に答える
10

argparseは使用しないでください。代わりに。を使用してsys.argvください。argparse名前空間を作成するため、スクリプトを呼び出したときに使用した引数に応じて、値とともに常に「dict」が提供されます。

これが私が過去にしたことです:

args = parser.parse_args()
if len(sys.argv) == 1:
    parser.print_help()
    sys.exit()
return args
于 2018-01-04T23:22:47.370 に答える
7

私はそれが古いスレッドであることを知っていますが、他の人にも役立つかもしれないより直接的な解決策を見つけました:

引数が渡されたかどうかを確認できます。

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()戻ります。FalseNoneFalse0

それが役に立てば幸い。

于 2019-07-22T19:07:42.800 に答える
3

完全を期すために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によって言及されている名前空間オブジェクトはですargsparser.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つの属性を同時に提供できないことを確認したい場合にも役立ちます。

詳細については、以下を参照してください。

于 2017-03-28T22:00:58.033 に答える
1

2dvisioの概念を拡張して、ゼロ以外またはNoneの引数をカウントしました。

vm_opts = parser.parse_args()
v = vars(vm_opts)
n_args = sum([ 1 for a in v.values( ) if a])
于 2016-11-16T16:42:55.993 に答える
0

すべての入力で同じである単一のタイプの引数が渡されたかどうかを確認する最も単純なケースでは、とを使用して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()より複雑な場合の論理演算子を受け入れます。

于 2021-01-22T18:00:37.513 に答える