条件付き実行のためにステートメント付きのPythonを使用できますか?
-
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()