この問題を外部から解決する試みとして、OptionParser クラスを OptionParser のサブクラスに置き換えることで optparse モジュールにパッチを適用し、parse_args メソッドをオーバーロードし、新しいdelayed_parse_args メソッドを公開する初期実装があります。他の誰かが役に立つと思うか、改善できる場合に備えて、このソリューションのスニペットを共有しています。
optparse_patch.py
import optparse
def patch_opt_parser():
optparse.stashed_parsers = {}
class OptionParserEx(optparse.OptionParser):
def delayed_parse_args(self, callback):
optparse.stashed_parsers[self] = callback
def parse_args(self, args=None, values=None):
for parser, callback in getattr(optparse,"stashed_parsers").items():
# add all the option_list & option_groups from the individual
# parsers in stashed_parsers to `self`
for parser, callback in getattr(optparse,"stashed_parsers").items():
# update `parser` to inherit the option_lists and option_groups from
# self. then ....
_o, _a = optparse._OptionParser.parse_args( parser, args, values )
callback( _o, _a t)
return getattr(optparse,"_OptionParser").parse_args(self, args, values)
optparse._OptionParser = optparse.OptionParser
optparse.OptionParser = OptionParserEx
patch_opt_parser()
これにより、サブモジュールは予想されるオプションを「隠し」、モジュールのクライアントが実際に OptionParser を提供し、独自の OptionParser で parse_args メソッドを呼び出すときに、後の段階でコマンド ライン オプションを評価することができます。このようなユースケースの例は次のとおりです。
モジュール.py
import optparse_patch
import optparse
parser = optparse.OptionParser()
group = optparse.OptionGroup(parser, "module options")
group.add_option("-f", dest="flip", action="store_true")
parser.add_option_group(group)
def cli_callback ( opts, args ):
if opts.flip:
print "flip"
opts, args = parser.delayed_parse_args ( cli_callback )
main.py
import module
import optparse
myparser = optparse.OptionParser()
mygroup = optparse.OptionGroup(myparser, "main options")
mygroup.add_option("-j", dest="jump", action="store_true")
myparser.add_option_group(mygroup)
opts, args = myparser.parse_args()
if opts.jump:
print "jump"
プログラム main.py を呼び出すと、次の出力が得られます。
python main.py --help
Usage: main.py [options]
Options:
-h, --help show this help message and exit
module options:
-f
main options:
-j
python main.py -j -f
flip
jump