条件付き実行のためにステートメント付きのPythonを使用できますか?

StackOverflow https://stackoverflow.com/questions/4314338

  •  29-09-2019
  •  | 
  •  

質問

次のセマンティクスをサポートするコードを作成しようとしています。

with scope('action_name') as s:
  do_something()
  ...
do_some_other_stuff()

とりわけ(セットアップ、クリーンアップ)スコープは、このセクションが実行されるかどうかを決定する必要があります。
たとえば、ユーザーがプログラムを「Action_Name」にバイパスするようにプログラムを構成した場合、Scope()が評価された後、do_something()を最初に呼び出すことなく実行されます。
私はこのコンテキストマネージャーを使用してそれをやろうとしました:

@contextmanager
def scope(action):
  if action != 'bypass':
    yield

しかし、手に入れました RuntimeError: generator didn't yield 例外(いつ action'bypass').
私は、より冗長なオプションの実装に戻ることなく、これをサポートする方法を探しています:

with scope('action_name') as s:
  if s.should_run():
    do_something()
    ...
do_some_other_stuff()

誰かが私がこれをどのように達成できるか知っていますか?
ありがとう!

PS私はPython2.7を使用しています

編集:
ソリューションは必ずしも頼る必要はありません with ステートメント。私はそれなしでそれを表現する方法を正確に知りませんでした。本質的に、私はコンテキストの形で何かを望んでいます(セットアップと自動クリーンアップをサポートし、含まれるロジックとは関係ありません)。
また、デコレーターを使用したソリューションの可能性についても考えました。例:

@scope('action_name') # if 'action_name' in allowed actions, do:
                      #   setup()
                      #   do_action_name()
                      #   cleanup()
                      # otherwise return
def do_action_name()
  do_something()

しかし、これらのスコープに基づいて、内部構造の多く(つまり、コードが機能に分割される方法)をあまり強制したくありません。
誰かが創造的なアイデアを持っていますか?

役に立ちましたか?

解決

基本的な言語構成の予想される動作を変更しようとしています。それは決して良い考えではなく、混乱につながるだけです。

あなたの仕事には何の問題もありませんが、少し単純化することができます。

@contextmanager 
def scope(action): 
  yield action != 'bypass'

with scope('action_name') as s: 
  if s: 
    do_something() 
    ... 
do_some_other_stuff() 

あなたの scope 代わりにそのクラスになる可能性があります __enter__ メソッドは、便利なオブジェクトを返します None そして、それは同じ方法で使用されます。

他のヒント

以下は機能しているようです。

from contextlib import contextmanager

@contextmanager
def skippable():
    try:
        yield
    except RuntimeError as e:
        if e.message != "generator didn't yield":
            raise

@contextmanager
def context_if_condition():
    if False:
        yield True

with skippable(), context_if_condition() as ctx:
    print "won't run"

考慮事項:

  • より良い名前を思いつく誰かが必要です
  • context_if_condition なしでは使用できません skippable しかし、それを強制する/冗長性を削除する方法はありません
  • それは、意図したよりも深い機能からRuntimeErrorをキャッチして抑制する可能性があります(カスタム例外はそこに役立つ可能性がありますが、それは全体の構成を厄介にします)
  • @Mark Ransomのバージョンを使用することほど明確ではありません

これができるとは思わない。コンテキストマネージャーをクラスとして実装しようとしましたが、 その後、 __exit__() 方法。

私はあなたと同じユースケースを持っていて、 条件付きライブラリ あなたがあなたの質問を投稿してから、誰かがその時点で役に立つように開発したこと。

サイトから、その使用は次のとおりです。

with conditional(CONDITION, CONTEXTMANAGER()):
    BODY()
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top