次のような形式の引数リストをサポートするスクリプトを作成したいと思います。
./myscript --env ONE=1,TWO=2 --env THREE=3
これが私の試みです:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
'--env',
type=lambda s: s.split(','),
action='append',
)
options = parser.parse_args()
print options.env
$ ./myscript --env ONE=1,TWO=2 --env THREE=3
[['ONE=1', 'TWO=2'], ['THREE=3']]
もちろん、後処理でこれを修正できます:
options.env = [x for y in options.env for x in y]
しかし、プログラムに新しいオプションを追加するときに、頭の中で「後でフラット化する必要があるもの」のリストを維持する必要がないように、argparse から直接フラット化されたリストを取得する方法があるかどうか疑問に思っています。
nargs='*'
の代わりにを使用する場合も、同じ質問が適用されますtype=lambda...
。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
'--env',
nargs='+',
action='append',
)
options = parser.parse_args()
print options.env
$ ./myscript --env ONE=1 TWO=2 --env THREE=3
[['ONE=1', 'TWO=2'], ['THREE=3']]
ベストアンサー1
編集: Python 3.8以降では、「extend」はstdlibで直接利用できます。3.8 以降のみをサポートする必要がある場合は、自分で定義する必要はなくなりました。stdlib の "extend" アクションの使用方法は、この回答で最初に説明されている方法とまったく同じです。
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> _ = parser.add_argument('--env', nargs='+', action='extend')
>>> parser.parse_args(["--env", "ONE", "TWO", "--env", "THREE"])
Namespace(env=['ONE', 'TWO', 'THREE'])
extend
残念ながら、デフォルトではアクションは提供されていませんArgumentParser
。しかし、登録するのはそれほど難しくありません。
import argparse
class ExtendAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
items = getattr(namespace, self.dest) or []
items.extend(values)
setattr(namespace, self.dest, items)
parser = argparse.ArgumentParser()
parser.register('action', 'extend', ExtendAction)
parser.add_argument('--env', nargs='+', action='extend')
args = parser.parse_args()
print(args)
デモ:
$ python /tmp/args.py --env one two --env three
Namespace(env=['one', 'two', 'three'])
あなたの例にあるは、kwarglambda
の意図された使用例からいくぶん外れていますtype
。そのため、 が実際にデータ内にある場合を正しく処理するのは面倒なので、代わりに空白で分割することをお勧めします,
。スペースで分割すると、この機能が無料で得られます。
$ python /tmp/args.py --env one "hello world" two --env three
Namespace(env=['one', 'hello world', 'two', 'three'])