【问题标题】:Python optparse defaults vs function defaultsPython optparse 默认值与函数默认值
【发布时间】:2009-10-02 23:11:22
【问题描述】:

我正在编写一个 python 脚本,我希望它既可以从命令行调用,又可以作为库函数导入。 理想情况下,命令行选项和函数应该使用同一组默认值。 让我在两个地方重用一组默认值的最佳方法是什么?

这是具有重复默认值的当前代码。

from optparse import OptionParser

def do_stuff(opt1="a", opt2="b", opt3="c"):
    print opt1, opt2, opt3

if __name__ == "__main__":
    parser = OptionParser()
    parser.add_option("--opt1", default="a")
    parser.add_option("--opt2", default="b")
    parser.add_option("--opt3", default="c")
    #parser.set_defaults(opt1="a")

    options, args = parser.parse_args()

    do_stuff(*args, **vars(options))

【问题讨论】:

    标签: python dry optparse


    【解决方案1】:

    我会通过反省感兴趣的函数来适当地设置选项和默认值来处理它。例如:

    import inspect
    from optparse import OptionParser
    import sys
    
    def do_stuff(opt0, opt1="a", opt2="b", opt3="c"):
        print opt0, opt1, opt2, opt3
    
    if __name__ == "__main__":
        parser = OptionParser()
        args, varargs, varkw, defaults = inspect.getargspec(do_stuff)
        if varargs or varkw:
          sys.exit("Sorry, can't make opts from a function with *a and/or **k!")
        lend = len(defaults)
        nodef = args[:-lend]
        for a in nodef:
          parser.add_option("--%s" % a)
        for a, d in zip(args[-lend:], defaults):
          parser.add_option("--%s" % a, default=d)
    
        options, args = parser.parse_args()
        d = vars(options)
        for n, v in zip(nodef, args):
          d[n] = v
    
        do_stuff(**d)
    

    【讨论】:

      【解决方案2】:

      这是解决方案 - 如果您只需要关键字参数,这很简单 - 只需使用 locals.update。以下同时处理位置和关键字 args(关键字 args 覆盖位置)。

      from optparse import OptionParser
      
      ARGS = {'opt1': 'a', 
              'opt2': 'b',
              'opt3': 'c'}
      
      def do_stuff(*args, **kwargs):
          locals = ARGS
      
          keys = ARGS.keys()
          keys.sort()
      
          if args:
              for key,arg in zip(keys,args):
                  locals.update({key: arg})
          if kwargs:
              locals.update(kwargs)
      
          print locals['opt1'], locals['opt2'], locals['opt3']
      
      if __name__ == "__main__":
          parser = OptionParser()
          for key,default in ARGS.items():
              parser.add_option('--%s' % key, default='%s' % default)
      
          options, args = parser.parse_args()
      
          do_stuff(*args, **vars(options))
          do_stuff()
          do_stuff('d','e','f')
          do_stuff('d','e','f', opt3='b')
          do_stuff(opt1='c', opt2='a', opt3='b')
      

      输出:

      a b c 
      a b c 
      d e f 
      d e b 
      c a b 
      

      【讨论】:

        【解决方案3】:

        Alex 的inspect 解决方案非常强大!

        对于轻量级程序,您也可以简单地使用:

        def do_stuff(opt1="a", opt2="b", opt3="c"):
            print opt1, opt2, opt3
        
        if __name__ == "__main__":
            from optparse import OptionParser
            opts = do_stuff.func_defaults
            parser = OptionParser()    
            parser.add_option("--opt1", default=opts[0], help="Option 1 (%default)")
            parser.add_option("--opt2", default=opts[1], help="Option 2 (%default)")
            parser.add_option("--opt3", default=opts[2], help="Option 3 (%default)")
        
            options, args = parser.parse_args()
        
            do_stuff(*args, **vars(options))
        

        【讨论】:

          猜你喜欢
          • 2015-03-15
          • 2013-03-16
          • 1970-01-01
          • 2010-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-01
          • 2019-05-08
          相关资源
          最近更新 更多