web-dev-qa-db-ja.com

必要なサブパーサーを含むArgparse

Python 3.4、サブパーサーでargparseを使用しようとしています。そして、Python 2.xここで、(サブパーサー/サブプログラムを示すために)位置引数を指定しないと、有用なエラーメッセージが表示されます。つまり、python2で、次のエラーメッセージが表示されます。

$ python2 subparser_test.py    
usage: subparser_test.py [-h] {foo} ...
subparser_test.py: error: too few arguments

https://stackoverflow.com/a/22994500/3061818 で提案されているようにrequired属性を設定していますが、Python 3.4.0:TypeError: sequence item 0: expected str instance, NoneType found-完全なトレースバック:

$ python3 subparser_test.py    
Traceback (most recent call last):
  File "subparser_test.py", line 17, in <module>
    args = parser.parse_args()
  File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1717, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1749, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1984, in _parse_known_args
    ', '.join(required_actions))
TypeError: sequence item 0: expected str instance, NoneType found

これは私のプログラムですsubparser_test.py- https://docs.python.org/3.2/library/argparse.html#sub-commands からの適応:

import argparse

# sub-command functions
def foo(args):
    print('"foo()" called')

# create the top-level parser
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
subparsers.required = True

# create the parser for the "foo" command
parser_foo = subparsers.add_parser('foo')
parser_foo.set_defaults(func=foo)

args = parser.parse_args()
args.func(args)

関連する質問: このargparseコードは、Python 2と3の間で異なる動作をするのはなぜですか?

51
ukrutt

subparsersdestを与える必要があります。

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='cmd')
subparsers.required = True

今:

1909:~/mypy$ argdev/python3 stack23349349.py
usage: stack23349349.py [-h] {foo} ...
stack23349349.py: error: the following arguments are required: cmd

この「欠落した引数」エラーメッセージを発行するには、コードはその引数に名前を付ける必要があります。位置引数(サブパースなど)の場合、その名前は(デフォルトで) 'dest'です。リンクしたSOの回答に、これに関する(マイナーな)メモがあります。

最後のPythonリリースでのargparseへのいくつかの 'パッチ'の1つは、 '必須'引数のテスト方法を変更しました。残念ながら、サブパーサーに関するこのバグを導入しました。次のリリースで修正されました(そうでない場合)。

更新

Py2でこのオプションのサブパーサーの動作が必要な場合、最良のオプションは、

ArgparseモジュールでPython 2.7 を使用してデフォルトのサブパーサーを設定する方法

関連するバグ/問題にいくつかの最近の活動がありました

https://bugs.python.org/issue925

更新

これに対する修正は作業中です: https://github.com/python/cpython/pull/3027

82
hpaulj