您能否举一个简单的plac 设置示例?以前很了解,现在更了解底层argparse。
您是否使用plac 直接调用函数,例如。
plac.call(main)
在内部plac 创建一个argparse.ArgumentParser(实际上是它自己的子类),用从函数签名派生的参数填充它。然后使用它解析的值调用该函数。
如果直接使用argparse,则创建解析器,填充它,然后调用它
args = parser.parse_args()
args 现在是一个 Namespace 对象,其属性以参数命名。也可以转换成字典。
如果您使用argparse 路由(可能仍在使用plac 创建解析器),您可以轻松检查args 中的属性,并将这些值与您的默认值或config 文件值进行比较.
IPython 实际上使用从配置文件(默认和自定义)派生的参数填充 argparse.parser。这使您可以在多个阶段覆盖配置默认值 - 使用自定义文件或使用命令行。
plac 应该比argparse 更容易,通过集成解析器创建和函数调用。但在您的情况下,将这些步骤分开可能会更好。
plac.call 的代码是:
def call(obj, arglist=sys.argv[1:], eager=True):
...
cmd, result = parser_from(obj).consume(arglist)
...
第一部分创建一个解析器;此解析器的参数基于注释装饰器。我的测试中的main 来自plac 文档。
In [22]: p=plac.parser_from(main)
In [23]: p
Out[23]: ArgumentParser(prog='ipython2.7', usage=None, description=None, version=None, formatter_class=<class 'argparse.RawDescriptionHelpFormatter'>, conflict_handler='error', add_help=True)
p.consume 是一个更长的函数,用于检查子解析器之类的东西。但在某些时候确实如此
ns, extraopts = self.parse_known_args(arglist)
# or self.parse_args
ns 是一个 argparse 命名空间,其参数由解析器设置 - 默认值和命令行参数。然后它使用来自ns 的值调用“函数”(分为Python 位置参数和关键字参数)。
所以你可以直接调用那个解析器:
In [25]: p.parse_args([]) # or with the default sys.argv[1:]
Out[25]: Namespace(args=[], kw={}, opt=None)
p.print_help() 还显示了它期望从命令行获得的参数,但格式整齐。
如果您想进一步了解argparse 的内容,可以查看p._actions,它是用于解析命令行的argparse.Action 对象列表。