Как я могу optparse OptionParser игнорировать недопустимые параметры?
В python OptionParser
, как могу ли я указать ему игнорировать параметры undefined, предоставленные в метод parse_args
?
например.
Я только определил опцию - foo
для моего экземпляра OptionParser
, но я вызываю parse_args
со списком
['- -foo ',' --bar ']
EDIT:
Меня не волнует, отфильтровывает ли он их из исходного списка. Я просто хочу, чтобы опции undefined игнорировались.
Причина, по которой я делаю это, заключается в том, что я использую интерфейс AddSption для добавления пользовательских параметров сборки. Однако некоторые из этих вариантов определяют объявление целей. Поэтому мне нужно разбирать их из sys.argv в разных точках script, не имея доступа ко всем опциям. В конце концов, Scons OptionParser верхнего уровня поймает все опции undefined в командной строке.
Ответы
Ответ 1
В запросе на синхронизацию в комментариях с другими ответами я отправляю свой взлом решения, которое дезактивирует входные данные, прежде чем передавать их родительскому OptionParser
:
import optparse
import re
import copy
import SCons
class NoErrOptionParser(optparse.OptionParser):
def __init__(self,*args,**kwargs):
self.valid_args_cre_list = []
optparse.OptionParser.__init__(self, *args, **kwargs)
def error(self,msg):
pass
def add_option(self,*args,**kwargs):
self.valid_args_cre_list.append(re.compile('^'+args[0]+'='))
optparse.OptionParser.add_option(self, *args, **kwargs)
def parse_args(self,*args,**kwargs):
# filter out invalid options
args_to_parse = args[0]
new_args_to_parse = []
for a in args_to_parse:
for cre in self.valid_args_cre_list:
if cre.match(a):
new_args_to_parse.append(a)
# nuke old values and insert the new
while len(args_to_parse) > 0:
args_to_parse.pop()
for a in new_args_to_parse:
args_to_parse.append(a)
return optparse.OptionParser.parse_args(self,*args,**kwargs)
def AddOption_and_get_NoErrOptionParser( *args, **kwargs):
apply( SCons.Script.AddOption, args, kwargs)
no_err_optparser = NoErrOptionParser(optparse.SUPPRESS_USAGE)
apply(no_err_optparser.add_option, args, kwargs)
return no_err_optpars
Ответ 2
Здесь один из способов добавления неизвестных аргументов в результат args
of OptionParser.parse_args
с простым подклассом.
from optparse import (OptionParser,BadOptionError,AmbiguousOptionError)
class PassThroughOptionParser(OptionParser):
"""
An unknown option pass-through implementation of OptionParser.
When unknown arguments are encountered, bundle with largs and try again,
until rargs is depleted.
sys.exit(status) will still be called if a known argument is passed
incorrectly (e.g. missing arguments or bad argument types, etc.)
"""
def _process_args(self, largs, rargs, values):
while rargs:
try:
OptionParser._process_args(self,largs,rargs,values)
except (BadOptionError,AmbiguousOptionError), e:
largs.append(e.opt_str)
И вот фрагмент, показывающий, что он работает:
# Show that the pass-through option parser works.
if __name__ == "__main__": #pragma: no cover
parser = PassThroughOptionParser()
parser.add_option('-k', '--known-arg',dest='known_arg',nargs=1, type='int')
(options,args) = parser.parse_args(['--shazbot','--known-arg=1'])
assert args[0] == '--shazbot'
assert options.known_arg == 1
(options,args) = parser.parse_args(['--k','4','--batman-and-robin'])
assert args[0] == '--batman-and-robin'
assert options.known_arg == 4
Ответ 3
По умолчанию не существует способа изменить поведение вызова на error()
, которое возникает при передаче опции undefined. Из документации в нижней части раздела как optparse обрабатывает ошибки:
Если поведение по умолчанию для обработки ошибок optparse не соответствует вашим потребностям, вам нужно будет подкласс OptionParser и переопределить его методы exit() и/или error().
Простейшим примером этого может быть:
class MyOptionParser(OptionParser):
def error(self, msg):
pass
Это просто сделает все вызовы error()
ничего не делать. Конечно, это не идеально, но я считаю, что это иллюстрирует то, что вам нужно будет сделать. Помните, что docstring из error()
и вы должны быть добры, когда продолжаете:
Распечатайте сообщение об использовании, включающее 'msg' в stderr и Выход. Если вы переопределите это в подклассе, он не должен возвращаться - он должен либо выйти, либо создать исключение.
Ответ 4
Python 2.7 (который не существовал, когда задавался этот вопрос) теперь предоставляет модуль argparse. Вы можете использовать ArgumentParser.parse_known_args()
для достижения цели этого вопроса.
Ответ 5
Это pass_through.py
пример из дистрибутива Optik.
#!/usr/bin/env python
# "Pass-through" option parsing -- an OptionParser that ignores
# unknown options and lets them pile up in the leftover argument
# list. Useful for programs that pass unknown options through
# to a sub-program.
from optparse import OptionParser, BadOptionError
class PassThroughOptionParser(OptionParser):
def _process_long_opt(self, rargs, values):
try:
OptionParser._process_long_opt(self, rargs, values)
except BadOptionError, err:
self.largs.append(err.opt_str)
def _process_short_opts(self, rargs, values):
try:
OptionParser._process_short_opts(self, rargs, values)
except BadOptionError, err:
self.largs.append(err.opt_str)
def main():
parser = PassThroughOptionParser()
parser.add_option("-a", help="some option")
parser.add_option("-b", help="some other option")
parser.add_option("--other", action='store_true',
help="long option that takes no arg")
parser.add_option("--value",
help="long option that takes an arg")
(options, args) = parser.parse_args()
print "options:", options
print "args:", args
main()