1

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

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

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

4

2 回答 2

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)
于 2012-07-26T02:11:15.533 回答
0

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

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

它在以下情况下运行良好:

  • 创建选项时,参数向量确实已经存在。这通常是正确的。
  • 我发现所有具有可选值的运动参数的所有程序都需要将给定值附加为--option=valueor-ovalue而不是--option valueor -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)
于 2014-04-02T08:40:49.337 回答