2012-07-26 61 views
1

我試圖找出如何從optparse傳遞可選參數傳遞可選參數。我遇到的問題是,如果沒有指定optparse選項,它默認爲None類型,但是如果我將None類型傳遞給函數,它會對我大喊,而不是使用默認(這是可以理解和有效的)。從optparse

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

的問題是,我該如何使用該功能的默認設置可選參數,但仍然在通過用戶輸入,如果有,而無需if語句數量龐大的輸入。

回答

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) 
+0

謝謝,這確實起作用。我希望有一個更少的黑客攻擊方式,而不是一個字典和刪除None類型。 – Kyo 2012-07-26 17:31:30

0

thebops封裝(pip install thebopshttps://bitbucket.org/therp/thebops)的opo模塊包含一個add_optval_option功能。 這使用了一個附加的關鍵字參數empty,它指定了在沒有值的情況下使用該選項時要使用的值。如果在命令行中找到一個選項字符串,則將此值注入參數列表。

這仍然是hackish的,但至少它是做了一個簡單易用的功能...

它運作良好,在下列情況下:

  • 參數向量不存在時該選項已創建。這通常是正確的。
  • 我發現所有的程序與可選值的運動參數要求價值爲--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)