parser.add_argument(...)
コードで定義された定数を使用して、指定された引数をマップするように作成したいと思います。
私が次のものを持っているとしましょう
import argparse
# Both are the same type
CONST_A = <something>
CONST_B = <otherthing>
parser = argparse.ArgumentParser()
parser.add_argument(...)
# I'd like the following to be true:
parser.parse_args("--foo A".split()).foo == CONST_A
parser.parse_args("--foo B".split()).foo == CONST_B
代わりに何を置くことができ...
ますか?
私ができる最善のことconst
は:
import argparse
# Both are the same type
CONST_A = 10
CONST_B = 20
parser = argparse.ArgumentParser()
status_group = parser.add_mutually_exclusive_group(required=True)
status_group.add_argument("-a", const=CONST_A, action='store_const')
status_group.add_argument("-b", const=CONST_B, action='store_const')
# I'd like the following to be true:
print parser.parse_args("-a".split()).a == CONST_A # True
print parser.parse_args("-b".split()).b == CONST_B # True
定数はTWのodifferent属性に保存されていることを注意a
してb
いない、魔女のスーツ私:(
最も簡単な方法は、@ hpauljが行っtype=
たadd_argument
ようにオプションを利用することですが、ファクトリ関数で一般化することもできます。
def argconv(**convs):
def parse_argument(arg):
if arg in convs:
return convs[arg]
else:
msg = "invalid choice: {!r} (choose from {})"
choices = ", ".join(sorted(repr(choice) for choice in convs.keys()))
raise argparse.ArgumentTypeError(msg.format(arg,choices))
return parse_argument
次に、...
単に使用する代わりにtype=argconv(A=CONST_A, B=CONST_B)
:
parser.add_argument("--foo", type=argconv(A=CONST_A, B=CONST_B))
そして、すべてがあなたの例で望むように機能します。
以下は私が投稿した最初の回答です。それはまだ有効ですが、上記の解決策ほど単純ではありません。
別の方法は、結果を継承しargparse.ArgumentParser
てオーバーライドするクラスを作成し、parse_args
生成された結果を変更することです。
import argparse
class MappedParser(argparse.ArgumentParser):
mapping = {} #backup if you don't use def_mapping
def def_mapping(self,**options):
self.mapping = options
def parse_args(self,args=None,namespace=None):
result = argparse.ArgumentParser.parse_args(self,args,namespace)
for name,options in self.mapping.items(): #by default this is is empty so the loop is skipped
if name in result:
key = getattr(result,name)
if key in options:
replace_with = options[key]
setattr(result,name,replace_with)
else:
self.error("option {name!r} got invalid value: {key!r}\n must be one of {valid}".format(name=name,key=key,valid=tuple(options.keys())))
return #error should exit program but I'll leave this just to be safe.
return result
このようにして、(例の)プログラムの残りの部分は次のようになります。
# There is nothing restricting their type.
CONST_A = "<something>"
CONST_B = ["other value", "type is irrelevent"]
parser = MappedParser() #constructor is same
parser.def_mapping(foo={"A":CONST_A, "B":CONST_B})
parser.add_argument("--foo") # and this is unchanged
# the following is now true:
print(parser.parse_args("--foo A".split()).foo is CONST_A)
print(parser.parse_args("--foo B".split()).foo is CONST_B)
#note that 'is' operator works so it is even the same reference
#this gives decent error message
parser.parse_args("--foo INVALID".split())
print("when parser.error() is called the program ends so this never is printed")
次のようなオプションを追加します。
parser.def_mapping(foo={"A":CONST_A, "B":CONST_B,"C":"third option"})
または次のような追加の引数:
parser.def_mapping(foo={"A":CONST_A, "B":CONST_B},
conv={"int":int,"float":float})
また、で指定されていない追加の引数はそのdef_mapping
ままにしておくので、実装は非常に簡単です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加