我有一个使用argparse和位置参数的小程序。我试图通过使用环境变量来设置该参数,但是没有让它工作。
我看过这篇文章:Setting options from environment variables when using argparse提到了同样的问题,但没有提到位置论证。
这是到目前为止的代码:
import argparse
import os
class EnvDefault(argparse.Action):
def __init__(self, envvar, required=True, default=None, **kwargs):
if not default and envvar:
if envvar in os.environ:
default = os.environ[envvar]
if required and default:
required = False
super(EnvDefault, self).__init__(default=default, required=required, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('testvar', help="Test variable", action=EnvDefault, envvar='TEST_VAR')
parser.add_argument('--othervar', help="Other variable", action='store_true')
args = parser.parse_args()
if not args.testvar: exit(parser.print_usage())
print args.testvar
返回此内容:
$ TEST_VAR="bla" ./test.py
usage: test.py [-h] [--othervar] testvar
test.py: error: too few arguments
答案 0 :(得分:2)
You need to make positional argument optional, try nargs='?'
:
...
parser.add_argument('testvar', help="Test variable", action=EnvDefault,
envvar='TEST_VAR', nargs='?')
...
Note that output changes slightly:
$ python test.py
usage: test.py [-h] [--othervar] [testvar]
Note: There's one side effect - it doesn't return error, even if env variable is not set.
答案 1 :(得分:1)
too few
错误消息表明您的Python / argparse版本稍旧。这是生成消息的代码。它发生在解析结束时:
# if we didn't use all the Positional objects, there were too few
# arg strings supplied.
if positionals:
self.error(_('too few arguments'))
# make sure all required actions were present
for action in self._actions:
if action.required:
if action not in seen_actions:
name = _get_action_name(action)
self.error(_('argument %s is required') % name)
positionals
启动所有位置参数的列表,这些参数在与参数字符串匹配时被删除。所以它正在测试是否有任何匹配。
请注意,required
属性的测试发生在此位置测试之后,因此更改它,就像您的Action一样,没有帮助。
使位置可选的唯一方法是使用nargs
- ?要么 *。一个空的字符串列表与那些匹配,因此总是消耗这样的位置。
检查这些文档。 const
参数可能很有用。
最新版本删除if positionals
测试,仅使用required
测试生成未使用的参数列表。您的特殊操作可能适用于该代码。