Решение Марка Родди будет работать, но оно требует модификации атрибута объекта синтаксического анализатора во время выполнения и не поддерживает форматирование альтернативных опций, отличное от - или -.
Немного менее сложным решением является изменение массива sys.argv перед запуском optparse и вставка пустой строки ("") после переключателя, который не должен иметь аргументов.
Единственным ограничением этого метода является то, что ваши параметры по умолчанию имеют предсказуемое значение, отличное от того, которое вы вставляете в sys.argv (я выбрал None для примера ниже, но это действительно не имеет значения).
Следующий код создает пример парсера и набор опций, извлекает массив разрешенных ключей из парсера (используя немного магии переменной экземпляра), а затем перебирает 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.
...