将命令行参数解析与对象初始化相关联

时间:2015-12-11 17:54:19

标签: python argparse object-initializer

我有一个包含大约十二个对象变量的类。与每个变量一起,我想提供一个默认值,一个帮助字符串(用于argparse)和一个注释字符串(用于写入数据文件)。我希望能够通过以下方式实例化对象:

  1. 为init方法提供显式值
  2. 提供要在命令行上使用的值
  3. 采用默认值
  4. 以上的某种组合。
  5. 当我只有两个对象变量时,我在init函数的声明中提供了默认值,我在创建参数解析器时复制了这些和帮助字符串等。但是对于许多变量,它变得非常混乱。 / p>

    下面的修剪后的示例代码是我目前的解决方案,我很满意,完全符合我的要求,而且效果非常好。但是,我有两个问题:

    1. 是pythonic吗?
    2. 肯定这已经是一个已经解决的问题,并且有一个标准"这样做的方法?
    3. 我确实环顾四周,搜索了一下,但我没有设法找到现有的解决方案。

      # invoke with python demoArgs.py -a 15 -b 25 -c text
      
      import argparse
      
      class Foo:
          defaults = {'a':10,'b':20, 'c':"outFile"}
          helpDefs = {'a' : 'the first parameter',
                      'b' : 'the second paramter',
                      'c' : 'the third paramter'}
      
          @staticmethod
          def parse_args():
              parser = argparse.ArgumentParser()
              for key in Foo.defaults:
                  parser.add_argument('-'+ key, help = Foo.helpDefs[key], 
                                        default = Foo.defaults[key])
              return vars(parser.parse_args())
      
          def __init__(self, a = defaults['a'], b = defaults['b'], c = defaults['c']):
              self.a = a
              self.b = b
              self.c = c
      
          def report(self):       
              for key in sorted(vars(self)):
                  print key, "val = ",  getattr(self,key), \
                             ", help = ", self.helpDefs[key], \
                             ", def = ",  self.defaults[key]
      
      def main():
          print "\n an object using all of the defaults"
          a = Foo()
          a.report()
      
          print "\n an object using the command line values"
          args = Foo.parse_args()
          b = Foo(**args)
          b.report()
      
          print "\n an object using values specified in the code"
          c = Foo(30,40,"object")
          c.report()
      
          print "\n an object using a perverse combination"
          args = Foo.parse_args()
          d = Foo(50, c = args['c'])
          d.report()
      
      
      if __name__ == '__main__':
         main()
      

1 个答案:

答案 0 :(得分:0)

至于它是“pythonic” - 我会说不。 Argparse已经非常强大了。想要使用你的库的人必须仔细了解它是如何工作的以及它如何包装其他东西(这也需要理解它包装的东西)。这种努力是否值得,这是有争议的。在短期内你最好只使用argparse,而不是试图简化已经完成工作的东西(恕我直言)。

关于问题#2 - 我严重怀疑其他人是否曾试图这样做。大多数人通常会坚持使用stdlib。它更简单,并且可以在python可以运行的所有平台上使用。

当然,这些答案都不能阻止你做你喜欢的事。