argparseオプション引数が設定されているかどうかを確認します


112

オプションのargparse引数がユーザーによって設定されているかどうかを確認したいと思います。

issetを使用して安全に確認できますか?

このようなもの:

if(isset(args.myArg)):
    #do something
else:
    #do something else

これは、float / int / stringタイプの引数でも同じように機能しますか?

デフォルトのパラメータを設定して確認することもできます(たとえば、myArg = -1を設定するか、文字列の ""、または "NOT_SET")。ただし、最終的に使用する値は、スクリプトの後半でのみ計算されます。したがって、デフォルトとして-1に設定し、後で別の値に更新します。これは、ユーザーが値を設定したかどうかを単にチェックする場合と比較すると、少し扱いに​​くいように見えます。


1
何がでしょうisset()(:PythonはPHPではありませんヒント)も?hasattr()代わりに、たぶん、という意味ですか?代わりに、オプションのデフォルトを設定するようにargparseを構成しないのはなぜですか?
Martijn Pieters

@MartijnPieters-はい、そうです。だから私は単にif(args.myArg)を確認できますか:...
Madeleine P. Vincent

回答:


146

オプションの引数(で指定--)が指定されてNoneいない場合は、に初期化されると思います。したがって、でテストできますis not None。以下の例を試してください:

import argparse as ap

def main():
    parser = ap.ArgumentParser(description="My Script")
    parser.add_argument("--myArg")
    args, leftovers = parser.parse_known_args()

    if args.myArg is not None:
        print "myArg has been set (value is %s)" % args.myArg

「is None」テストと「is not None」テストは、期待どおりに機能します。ありがとう。
Madeleine P. Vincent

39
残念ながらそれは機能しません、そして引数はそれがdefault定義された値を得ました。
kcpr

6
を設定する場合defaultでも、docsで説明されているように、値を設定nargs='?'して提供できます。argが存在しない場合は使用され、argが値なしで指定された場合はそれが使用され、それ以外の場合は指定された値が使用されます。and のみで、値が指定されていない場合は使用され、値が指定されていない場合は使用されます。それ以外の場合は指定された値が使用されます。constdefaultconstdefaultnargs='?'defaultNone
Ioannis Filippidis 2017年

@IoannisFilippidisを使用する場合、action= "store_true"またはaction="store_const", const="yourconst"その引数を使用して他の値を格納できない場合。デフォルトを使用している場合、これは機能しません。私自身では、argparserからすべてのデフォルトを削除しdef defaults():、ConfigParser、ArgumentParser、およびデフォルト値を希望する順序で混合する別の関数内ですべて処理しました
m3nda

@ erm3ndaの設定については言及しませんでしたaction。答えはを使用しませんaction。あなたが言及するアクションは、(観察したように)1つの特定の方法で動作するように文書化されています。ただし、アクションを定義する必要はありません。
Ioannis Filippidis 2017年

37

@Honzaのメモis Noneは良いテストです。これがデフォルトdefaultであり、ユーザーはそれを複製する文字列を与えることはできません。

別のを指定してdefault='mydefaultvalue、それをテストできます。しかし、ユーザーがその文字列を指定するとどうなるでしょうか。それは設定としてカウントされますか?

も指定できますdefault=argparse.SUPPRESS。その後、ユーザーが引数を使用しないと、args名前空間に表示されません。しかし、より複雑になる可能性のあるテスト:

args.foo # raises an AttributeError
hasattr(args, 'foo')  # returns False
getattr(args, 'foo', 'other') # returns 'other'

内部的にparserはのリストを保持し、seen_actionsそれを「必須」および「相互排他的」テストに使用します。ただし、以外ではご利用いただけませんparse_args


22

このオプションdefault=argparse.SUPPRESSを使用することが最も理にかなっていると思います。次に、引数がかどうかをチェックする代わりに、引数がnot Noneかどうかをチェックしますin結果の名前空間ます。

例:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--foo", default=argparse.SUPPRESS)
ns = parser.parse_args()

print("Parsed arguments: {}".format(ns))
print("foo in namespace?: {}".format("foo" in ns))

使用法:

$ python argparse_test.py --foo 1
Parsed arguments: Namespace(foo='1')
foo in namespace?: True
引数が指定されていません:
$ python argparse_test.py
Parsed arguments: Namespace()
foo in namespace?: False

これは、Python 3.7.5(Anaconda)では動作しません。結果が出ましたtestfoo.py: error: argument --foo: expected one argument
マイクワイズ

@MikeWise --foo値なしで使用する場合(つまり1、この例)、関数で指定する必要nargs=0がありadd_argumentます。
Erasmus Cedernaes

回答で指定されているように、コードをコピーして貼り付けます。多分あなたはそれを編集するべきですか?action='store_true'実際のコードでは、代わりに以下の答えを使用しました。
マイクワイズ

@MikeWiseでスクリプトを実行しましたpython argparse_test.py --foo 1か?
Erasmus Cedernaes

11

オプションで渡されたフラグstore_truestore_false引数アクションオプションを確認できます。

import argparse

argparser = argparse.ArgumentParser()
argparser.add_argument('-flag', dest='flag_exists', action='store_true')

print argparser.parse_args([])
# Namespace(flag_exists=False)
print argparser.parse_args(['-flag'])
# Namespace(flag_exists=True)

このように、条件によるチェックを心配する必要はありませんis not NoneTrueまたはを確認するだけFalseです。これらのオプションの詳細については、こちらのドキュメントをご覧ください。


1
これは、値を持つ引数が設定されているかどうかを知るために解決しません。ここでの主な問題は、argsの値がdefaul = ""から来ているのか、それともユーザーが指定したのかを知ることです。
m3nda 2017年

5

引数が定位置の場合(つまり、「-」または「-」の接頭辞がなく、引数(通常はファイル名)のみ)の場合、nargsパラメータを使用してこれを行うことができます。

parser = argparse.ArgumentParser(description='Foo is a program that does things')
parser.add_argument('filename', nargs='?')
args = parser.parse_args()

if args.filename is not None:
    print('The file name is {}'.format(args.filename))
else:
    print('Oh well ; No args, no problems')

3

これがargparse変数を使用しているかどうかを確認するための私の解決策です

import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-1", "--first", required=True)
ap.add_argument("-2", "--second", required=True)
ap.add_argument("-3", "--third", required=False) 
# Combine all arguments into a list called args
args = vars(ap.parse_args())
if args["third"] is not None:
# do something

これは、私が使用して自分のプログラムで機能するように適合させた上記の回答に、より洞察を与えるかもしれません。


0

@Honza Osobneによる(現在受け入れられている)回答に対する@kcprのコメントに対処するため

残念ながらそれは機能しません、そして引数はそれが定義されたデフォルト値を得ました。

オプションをNamespace提供するオブジェクトabd と比較することで引数が提供されているかどうかを最初に確認default=argparse.SUPPRESSでき(@hpauljと@Erasmus Cedernaesの回答とこのpython3ドキュメントを参照)、提供されていない場合は、デフォルト値に設定します。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--infile', default=argparse.SUPPRESS)
args = parser.parse_args()
if 'infile' in args: 
    # the argument is in the namespace, it's been provided by the user
    # set it to what has been provided
    theinfile = args.infile
    print('argument \'--infile\' was given, set to {}'.format(theinfile))
else:
    # the argument isn't in the namespace
    # set it to a default value
    theinfile = 'your_default.txt'
    print('argument \'--infile\' was not given, set to default {}'.format(theinfile))

使用法

$ python3 testargparse_so.py
argument '--infile' was not given, set to default your_default.txt

$ python3 testargparse_so.py --infile user_file.txt
argument '--infile' was given, set to user_file.txt

0

args変数を「args = parser.parse_args()」で定義した後は、argsサブセット変数のすべてのデータも含まれています。変数が設定されているかどうかを確認するには、「action = "store_true"が使用されていると想定しない...

if args.argument_name:
   # do something
else:
   # do something else
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.