4

次のセットアップ例があります。

|-- main_script.py
`-- module
    |-- __init__.py
    `-- submodule.py

main_script の内容は次のとおりです。

import optparse
import module

parser = optparse.OptionParser()
group = optparse.OptionGroup("submodules options")
group.add_option("","--main_script.bar", dest="bar", action="store_true")
parser.add_option_group(group)

opts,args = parser.parse_args()

if opts.bar:
    print ("Bar")

submodule.py の内容は次のとおりです。

import optparse
parser = optparse.OptionParser()
group = optparse.OptionGroup(parser, "submodules options")
group.add_option("","--module.submodule.foo", dest="foo", action="store_true")
parser.add_option_group(group)

opts,args = parser.parse_args()

if opts.foo:
    print ("Foo")

main_script はサブモジュールをインポートするため、サブモジュールからの parse_args が呼び出されます。OptionParser のこれらのインスタンスを組み合わせて、オプションの競合がある場合にエラーを発生させる方法はありますか?

4

2 に答える 2

2

最も簡単な方法は、ロジックを関数に分割することです。そもそもグローバル モジュール スコープでロジックを実行するのではなく、if name == "__main__"ラッパー コンストラクトを使用する必要があります。

オプションを定義する必要がある各モジュールに関数add_options(parser)を定義し、これを呼び出す前にルート レベルで呼び出すことができparse_argsます。

import optparse
import submodule

def add_options(parser):
    parser.add_option(...)

def main():
    parser = optparse.OptionParser()
    add_options(parser)
    submodule.add_options(parser)
    opts, args = parser.parse_args()
    #...

if __main__ == "__main__":
    main()
于 2011-10-24T06:33:27.597 に答える
0

この問題を外部から解決する試みとして、OptionParser クラスを OptionParser のサブクラスに置き換えることで optparse モジュールにパッチを適用し、parse_args メソッドをオーバーロードし、新しいdelayed_pa​​rse_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
于 2011-10-25T02:25:57.853 に答える