【问题标题】:Python: How to get all default values from argparsePython:如何从 argparse 获取所有默认值
【发布时间】:2017-11-16 11:28:13
【问题描述】:

当使用模块optparse 时,我可以获得所有命令行参数的所有默认值,如下所示:

import optparse

if __name__ == '__main__':
    parser = optparse.OptionParser(usage='pokus --help')
    parser.add_option("-d", "--debug", action='store_true', dest="debug",
                      default=False, help='Enabling debugging.')
    options, args = parser.parse_args()
    print(parser.defaults)

由于optparse 已被弃用,明智的做法是重写代码以使用argparse 模块。但是我找不到任何方法如何获取添加到解析器对象的所有命令行参数的所有默认值:

import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser(usage='pokus --help')
    parser.add_argument("-d", "--debug", action='store_true', dest='debug',
                        default=False, help='Enabling debugging.')   
    args = parser.parse_args()
    # <---- How to get default values for all arguments here?
    # Not: vars(args)

我想在使用 (./app.py -d) 或不使用任何命令行参数 (./app.py) 运行程序时获取所有默认值。

【问题讨论】:

  • 当省略开关时,默认值在args 对象上设置。您是否需要访问这些内容?
  • 因此,在您的示例中,当您不使用 -d 运行程序时,args.debug 设置为 False。当您使用-d 运行时,您需要知道默认为False 的用例是什么?
  • 你考虑过使用docopt吗?
  • 我找到了解决方案,当我运行defaults = vars(parser.parser-args([])) 时,我会得到包含所有默认值的字典。顺便说一句:当我有很多参数并且需要区分默认值和在命令行中指定的值时,我需要它。

标签: python argparse default-value


【解决方案1】:

我找到了解决方案:

import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser(usage='pokus --help')
    parser.add_argument("-d", "--debug", action='store_true', dest='debug',
                        default=False, help='Enabling debugging.')
    parser.add_argument("-e", "--example", action='store', dest='example',
                        default="", help='Example of argument.')
    # Arguments from command line and default values
    args = vars(parser.parse_args())
    # Only default values
    defaults = vars(parser.parse_args([]))

然后你可以比较argsdefaults的值,区分默认值和命令行的值。

【讨论】:

    【解决方案2】:

    如果不想解析空输入字符串,可以使用parser对象中的get_default方法:

    import argparse
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(usage='pokus --help')
        parser.add_argument("-d", "--debug", action='store_true', dest='debug',
                            default=False, help='Enabling debugging.')   
        args = parser.parse_args()
    
        # To get a single default:
        d_default = parser.get_default('d')
    
        # To get all defaults:
        all_defaults = {}
        for key in vars(args):
            all_defaults[key] = parser.get_default(key)
    
        # Edit: Adding an alternative one-liner (using dict comprehension):
        all_defaults = {key: parser.get_default(key) for key in vars(args)}
    

    【讨论】:

    • 感谢您的回答。这似乎也是一个可行的解决方案。
    • 我必须使用 parser.get_default('debug') 才能工作。
    【解决方案3】:

    聚会有点晚了,但这是一个函数(带有额外的单元测试),我在几个案例中使用它来获取默认参数而不必先解析(如果你有的话,先解析可能会很烦人所需的参数尚不可用)

    def get_argparse_defaults(parser):
        defaults = {}
        for action in parser._actions:
            if not action.required and action.dest != "help":
                defaults[action.dest] = action.default
        return defaults
    
    def get_argparse_required(parser):
        required = []
        for action in parser._actions:
            if action.required:
                required.append(action.dest)
        return required
    
    parser = argparse.ArgumentParser()
    optional_defaults_dict = get_argparse_defaults(parser)
    required_list = get_argparse_required(parser)
    

    class TestDefaultArgs(unittest.TestCase):
    
        def test_get_args(self):
            parser = argparse.ArgumentParser()
            parser.add_argument('positional_arg')
            parser.add_argument('--required_option', required=True)
            parser.add_argument('--optional_with_default', required=False, default="default_value")
            parser.add_argument('--optional_without_default', required=False)
    
            required_args = get_argparse_required(parser)
            self.assertEqual(['positional_arg', 'required_option'], required_args)
    
    
            default_args = get_argparse_defaults(parser)
            self.assertEqual({'optional_with_default': 'default_value',
                              'optional_without_default': None},
                             default_args)
    

    【讨论】:

      【解决方案4】:

      为了您的信息,这里是解析开始时初始化defaults的代码:

      def parse_known_args(...):
          ....
          # add any action defaults that aren't present
          for action in self._actions:
              if action.dest is not SUPPRESS:
                  if not hasattr(namespace, action.dest):
                      if action.default is not SUPPRESS:
                          setattr(namespace, action.dest, action.default)
      
          # add any parser defaults that aren't present
          for dest in self._defaults:
              if not hasattr(namespace, dest):
                  setattr(namespace, dest, self._defaults[dest])
          ...
      

      所以它遍历parser._actions 列表,收集action.default 属性。 (action 是由parser.add_argument 方法创建的Action 类对象。)。它还检查self._defaults。这是由parse.set_defaults 方法修改的字典。这可用于设置不直接链接到操作的defaults

      解析命令行后,可以评估命名空间中的默认字符串(使用action.type),例如将default='1' 转换为整数1。

      处理argparse 中的默认值并非易事。你的 parse_args([]) 可能是最简单的,只要解析器可以接受(即没有任何必需的参数)。

      我现在不知道optparse 设置defaults 属性。有一个不平凡的方法,optparse.OptionParser.get_default_values

      【讨论】:

        【解决方案5】:

        对于上面的例子:

        import argparse
        
        if __name__ == '__main__':
           parser = argparse.ArgumentParser(usage='pokus --help')
           parser.add_argument("-d", "--debug", action='store_true', dest='debug',
                            default=False, help='Enabling debugging.') 
        

        A.tuple 格式获取所有默认值:

        In[1]: args = parser.parse_known_args()[0]
        In[2]: args._get_kwargs()
        Out[1]: [('debug', False)]
        

        访问每个项目:

        In[3]: args.debug
        Out[2]: False
        

        B.dictionary 格式获取值及其默认值

        In[4]: dict_args = parser.parse_known_args()[0].__dict__
        In[5]: dict_args
        Out[3]: {'debug': False}
        

        并访问每个键:

        In[6]: dict_args['debug']
        Out[4]: False
        

        或者迭代地打印它们:

        In[7]: for key in dict_args:
        ...        print('value for %s is: %s'% (key, dict_args[key]))
        
        Out[5]: value for debug is: False
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-08-05
          • 2019-11-20
          • 1970-01-01
          • 2017-02-20
          • 1970-01-01
          • 2017-09-27
          • 2022-01-25
          相关资源
          最近更新 更多