【问题标题】:Passing optional arguments from optparse从 optparse 传递可选参数
【发布时间】:2012-07-24 13:32:42
【问题描述】:

我试图弄清楚如何从 optparse 传递可选参数。我遇到的问题是,如果未指定 optparse 选项,它默认为 None 类型,但如果我将 None 类型传递给函数,它会对我大喊大叫而不是使用默认值(这是可以理解和有效的)。

conn = psycopg2.connect(database=options.db, hostname=options.hostname, port=options.port)

问题是,我如何将函数的默认值用于可选参数,但如果有输入而没有大量 if 语句,我仍然会传递用户输入。

【问题讨论】:

    标签: python python-2.6 optparse optional-arguments


    【解决方案1】:

    我的thebops 包(pip install thebopshttps://bitbucket.org/therp/thebops)的opo 模块包含一个add_optval_option 函数。 这使用了一个额外的关键字参数empty,它指定了在没有值的情况下使用该选项时要使用的值。如果在命令行中找到选项字符串之一,则将该值注入参数列表中。

    这仍然是hackish,但至少它是一个简单易用的功能......

    在以下情况下效果很好:

    • 创建选项时,参数向量已经存在。这通常是正确的。
    • 我发现的所有带有可选值的运动参数的程序都需要将 given 值附加为 --option=value-ovalue 而不是 --option value-o value

    也许我会调整 thebops.optparse 以支持 empty 参数;但我想先有一个测试套件来防止回归,最好是原始的 Optik / optparse 测试。

    这是代码:

    from sys import argv
    def add_optval_option(pog, *args, **kwargs):
        """
        Add an option which can be specified without a value;
        in this case, the value (if given) must be contained
        in the same argument as seen by the shell,
        i.e.:
    
        --option=VALUE, --option will work;
        --option VALUE will *not* work
    
        Arguments:
        pog -- parser or group
        empty -- the value to use when used without a value
    
        Note:
          If you specify a short option string as well, the syntax given by the
          help will be wrong; -oVALUE will be supported, -o VALUE will not!
          Thus it might be wise to create a separate option for the short
          option strings (in a "hidden" group which isn't added to the parser after
          being populated) and just mention it in the help string.
        """
        if 'empty' in kwargs:
            empty_val = kwargs.pop('empty')
            # in this case it's a good idea to have a <default> value; this can be
            # given by another option with the same <dest>, though
            for i in range(1, len(argv)):
                a = argv[i]
                if a == '--':
                    break
                if a in args:
                    argv.insert(i+1, empty_val)
                    break
        pog.add_option(*args, **kwargs)
    

    【讨论】:

      【解决方案2】:

      定义一个函数remove_none_values,为无值参数过滤字典。

      def remove_none_values(d):
          return dict((k,v) for (k,v) in d.iteritems() if not v is None)
      
      kwargs = {
        'database': options.db,
        'hostname': options.hostname,
        ...
      }
      conn = psycopg2.connect(**remove_none_values(kwargs))
      

      或者,定义一个函数包装器,在将数据传递给原始函数之前删除任何值。

      def ignore_none_valued_kwargs(f):
          @functools.wraps(f)
          def wrapper(*args, **kwargs):
              newkwargs = dict((k,v) for (k,v) in d.iteritems() if not v is None)
              return f(*args, **kwargs)
          return wrapper
      
      my_connect = ignore_none_valued_kwargs(psycopg2)
      conn = my_connect(database=options.db, hostname=options.hostname, port=options.port)
      

      【讨论】:

      • 谢谢,成功了。我希望有一种比制作 dict 和删除 None 类型更少的黑客攻击方式。
      猜你喜欢
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多