禁止 argparse 参数被覆盖
Disable argparse arguments from being overwritten
我有一个遗留 Python 应用程序,它使用 argparse 在其 CLI 中使用一些选项,例如:
parser = argparse.ArgumentParser()
parser.add_argument('-f', default='foo')
现在我需要删除这个选项,因为现在它的值不能被用户覆盖,但它必须采用默认值(比如示例中的 'foo')。有没有办法保留选项但防止它显示并被用户覆盖(这样我就可以保持其余代码不变)?
是的,你可以做到。解析器解析后(args = parser.parse_args()
)是一个NameSpace所以可以这样做:
parser = argparse.ArgumentParser()
args = parser.parse_args()
args.foo = 'foo value'
print(args)
>>> Namespace(OTHER_OPTIONS, foo='foo value')
我假设您想将 test
添加到您的解析器,因此您的原始代码仍然有效,但您不希望它作为用户的一个选项。
我认为 argparse
模块将此作为标准选项提供没有意义,但有几种简单的方法可以实现您想要的。
最明显的方法是在调用 parse_args()
之后覆盖该值(正如评论和另一个答案中已经提到的那样):
args.f = 'foo'
但是,用户可能不知道该选项不再受支持,应用程序现在假定 值“foo”。根据用例,最好就此警告用户。 argparse 模块有几个选项可以做到这一点。
另一种可能性是使用 Action class 来施展魔法。例如,如果用户提供的选项不再受支持,您可以打印警告,甚至可以使用 built-in 错误处理。
import argparse
class FooAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if values != 'foo':
print('Warning: option `-f` has been removed, assuming `-f foo` now')
# Or use the built-in error handling like this:
# parser.error('Option "-f" is not supported anymore.')
# You could override the argument value like this:
# setattr(namespace, self.dest, 'foo')
parser = argparse.ArgumentParser()
parser.add_argument('-f', default='foo', action=FooAction)
args = parser.parse_args()
print('option=%s' % args.f)
您也可以将选择限制为仅“foo”,并让 argparse
为其他值创建错误:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-f', default='foo', choices=['foo'])
args = parser.parse_args()
print('option=%s' % args.f)
调用 python test.py -f bar
将导致:
usage: test.py [-h] [-f {foo}]
test.py: error: argument -f: invalid choice: 'bar' (choose from 'foo')
不完全清楚您可以做什么,而不是使用解析器。你能编辑设置吗?还是只修改解析结果?
如果您可以编辑设置,则可以将 add_argument
行替换为
parser.setdefaults(f='foo')
https://docs.python.org/3/library/argparse.html#parser-defaults
-f
不会出现在用法或帮助中,但会出现在args
中
或者您可以保留它,但禁止显示帮助
parser.add_argument('-f', default='foo', help=argparse.SUPPRESS)
https://docs.python.org/3/library/argparse.html#help
设置解析后的值也可以
我有一个遗留 Python 应用程序,它使用 argparse 在其 CLI 中使用一些选项,例如:
parser = argparse.ArgumentParser()
parser.add_argument('-f', default='foo')
现在我需要删除这个选项,因为现在它的值不能被用户覆盖,但它必须采用默认值(比如示例中的 'foo')。有没有办法保留选项但防止它显示并被用户覆盖(这样我就可以保持其余代码不变)?
是的,你可以做到。解析器解析后(args = parser.parse_args()
)是一个NameSpace所以可以这样做:
parser = argparse.ArgumentParser()
args = parser.parse_args()
args.foo = 'foo value'
print(args)
>>> Namespace(OTHER_OPTIONS, foo='foo value')
我假设您想将 test
添加到您的解析器,因此您的原始代码仍然有效,但您不希望它作为用户的一个选项。
我认为 argparse
模块将此作为标准选项提供没有意义,但有几种简单的方法可以实现您想要的。
最明显的方法是在调用 parse_args()
之后覆盖该值(正如评论和另一个答案中已经提到的那样):
args.f = 'foo'
但是,用户可能不知道该选项不再受支持,应用程序现在假定 值“foo”。根据用例,最好就此警告用户。 argparse 模块有几个选项可以做到这一点。
另一种可能性是使用 Action class 来施展魔法。例如,如果用户提供的选项不再受支持,您可以打印警告,甚至可以使用 built-in 错误处理。
import argparse
class FooAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if values != 'foo':
print('Warning: option `-f` has been removed, assuming `-f foo` now')
# Or use the built-in error handling like this:
# parser.error('Option "-f" is not supported anymore.')
# You could override the argument value like this:
# setattr(namespace, self.dest, 'foo')
parser = argparse.ArgumentParser()
parser.add_argument('-f', default='foo', action=FooAction)
args = parser.parse_args()
print('option=%s' % args.f)
您也可以将选择限制为仅“foo”,并让 argparse
为其他值创建错误:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-f', default='foo', choices=['foo'])
args = parser.parse_args()
print('option=%s' % args.f)
调用 python test.py -f bar
将导致:
usage: test.py [-h] [-f {foo}]
test.py: error: argument -f: invalid choice: 'bar' (choose from 'foo')
不完全清楚您可以做什么,而不是使用解析器。你能编辑设置吗?还是只修改解析结果?
如果您可以编辑设置,则可以将 add_argument
行替换为
parser.setdefaults(f='foo')
https://docs.python.org/3/library/argparse.html#parser-defaults
-f
不会出现在用法或帮助中,但会出现在args
或者您可以保留它,但禁止显示帮助
parser.add_argument('-f', default='foo', help=argparse.SUPPRESS)
https://docs.python.org/3/library/argparse.html#help
设置解析后的值也可以