Mark Roddy的解決方案可以工作,但它需要在運行時修改解析器對象的屬性,並且不支持 - 或 - 以外的其他選項格式。 一個稍微沒有涉及的解決方案是在運行optparse之前修改sys.argv數組,並在不需要參數的交換機之後插入一個空字符串(「」)。 這個方法的唯一約束是你的選項默認爲一個可預測的值,而不是你插入到sys.argv中的那個(我選擇None作爲下面的例子,但它確實沒關係)。
以下代碼創建了一個示例解析器和一組選項,從解析器中提取允許的開關數組(使用一點實例變量magic),然後遍歷sys.argv,並且每次找到 允許切換,它會檢查它是否在沒有任何參數後給出。如果在切換後沒有參數,則將在命令行 上插入空字符串。修改sys.argv之後,調用解析器,並且可以檢查其值爲「」的選項,並相應地執行操作。
#Instantiate the parser, and add some options; set the options' default values to None, or something predictable that
#can be checked later.
PARSER_DEFAULTVAL = None
parser = OptionParser(usage="%prog -[MODE] INPUT [options]")
#This method doesn't work if interspersed switches and arguments are allowed.
parser.allow_interspersed_args = False
parser.add_option("-d", "--delete", action="store", type="string", dest="to_delete", default=PARSER_DEFAULTVAL)
parser.add_option("-a", "--add", action="store", type="string", dest="to_add", default=PARSER_DEFAULTVAL)
#Build a list of allowed switches, in this case ['-d', '--delete', '-a', '--add'] so that you can check if something
#found on sys.argv is indeed a valid switch. This is trivial to make by hand in a short example, but if a program has
#a lot of options, or if you want an idiot-proof way of getting all added options without modifying a list yourself,
#this way is durable. If you are using OptionGroups, simply run the loop below with each group's option_list field.
allowed_switches = []
for opt in parser.option_list:
#Add the short (-a) and long (--add) form of each switch to the list.
allowed_switches.extend(opt._short_opts + opt._long_opts)
#Insert empty-string values into sys.argv whenever a switch without arguments is found.
for a in range(len(sys.argv)):
arg = sys.argv[a]
#Check if the sys.argv value is a switch
if arg in allowed_switches:
#Check if it doesn't have an accompanying argument (i.e. if it is followed by another switch, or if it is last
#on the command line)
if a == len(sys.argv) - 1 or argv[a + 1] in allowed_switches:
sys.argv.insert(a + 1, "")
options, args = parser.parse_args()
#If the option is present (i.e. wasn't set to the default value)
if not (options.to_delete == PARSER_DEFAULTVAL):
if options.droptables_ids_csv == "":
#The switch was not used with any arguments.
...
else:
#The switch had arguments.
...
這個變體的問題在於`--for = bar`將會不工作:`parser.py:error:--foo選項不會取值` – Tobias 2013-04-13 08:09:21