2017-08-29 6 views
1

Clickに基づくFlask CLIインフラストラクチャを使用してコマンドラインアプリケーションを実装しようとしています。そのインターフェイスは次のように動作するはずです:CLI(Click)内の複数のコンテキストオブジェクト

app.py -c config.cfg cmd_a 
app.py -c config.cfg cmd_b 

私は次のコードを持っている:

@click.group 
@click.option('-c', 'config') 
@click.pass_context 
def cli(ctx, config): 
    ctx.obj = ObjA(config) 
    ctx.obj = ObjB(config) # Just for illustration 

@cli.command() 
@click.pass_context() 
def cmd_a(ctx): 
    ctx.find_object(ObjA) 

@cli.command() 
@cli.pass_context() 
def cmd_b(ctx): 
    ctx.find_object(ObjB) 

cli() 

を問題は、私は-cフラグに基づいて、2つの異なるオブジェクトを作成し、するためにそれらの両方が利用できるようにする必要があり、あります基本的なコマンドは不可能と思われる。このための回避策はありますか?

Contextオブジェクトのmetaプロパティを使用することができますが、それは多くの定型文を書くことを意味します。

答えて

0

find_objectタイプによってparent contextのオブジェクトを検索します。複数のオブジェクトを使用する場合は、objを辞書にするのが最も簡単な方法です。ここでは例:

@click.group 
@click.option('-c', 'config') 
@click.pass_context 
def cli(ctx, config): 
    if ctx.obj is None: 
     ctx.obj = dict() 
    # add any data to obj here... 
    ctx.obj['a'] = 'example_A' 
    ctx.obj['b'] = 'example_B' 

@cli.command() 
@click.pass_context() 
def cmd_a(ctx): 
    # check prepared data 
    print(ctx.obj['a']) 

@cli.command() 
@cli.pass_context() 
def cmd_b(ctx): 
    # check prepared data 
    print(ctx.obj['b']) 

少し異なる方法 - objのためのカスタムクラスを使用します。

class Config(object): 

    def __init__(self, config): 
     # do something with config here ... 
     self.a = 'example_A' 
     self.b = 'example_B' 

# in your def cli() 
ctx.obj = Config(config) 
# in your commands you can works with your prepared data like this: 
print(ctx.obj.a) 
print(ctx.obj.b) 

・ホープ、このことができます。

+1

ありがとうございました! 'obj'のカスタムクラスを使うのは、私が本当に「純粋」ではないにもかかわらず、私にとって最良の方法のようです。ああ、ちょっとした修正 - 'find_object'は直接の親だけでなくコンテキスト階層全体を検索します。 – Teyras

+0

私は助けてうれしかった。がんばろう ; ) –

関連する問題