4

現在、グローバル変数を 2 つの値の間で切り替える 1 組の python 関数があります。それらをコンテキストマネージャーに変えて、ブロックとして使用できるようにしたいと思いますwith。ブロック内で変数を設定しますが、後で復元します。望ましい動作は次のとおりです。

>>> MODE
'user'
>>> mode_sudo()  # Sets MODE to 'sudo'...
>>> MODE
'sudo'
>>> mode_user()  # Sets MODE to 'user'...
>>> MODE
'user'
>>> with mode_sudo():
...    print MODE
'sudo'
>>> MODE
'user'

そのようなキメラは可能ですか?

更新:わかりやすくするために、コンテキスト マネージャーのみの実装を次に示します。

from contextlib import contextmanager

@contextmanager
def mode_sudo():
    global MODE
    old_mode = MODE
    MODE = 'sudo'
    yield
    MODE = old_mode

@contextmanager
def mode_user():
    global MODE
    old_mode = MODE
    MODE = 'user'
    yield
    MODE = old_mode

これらを w/oa キーワードで呼び出すと、ジェネレーターが返されます。プレーン バニラ関数呼び出しとチョコレート コンテキスト マネージャーの両方でモード反転動作を取得する方法はありますか?

4

2 に答える 2

5

次のようにします。

class mod_user:

    def __init__(self):
        global MODE
        self._old_mode = MODE
        MODE = "user"

    def __enter__(self):
        pass

    def __exit__(self, *args, **kws):
        global MODE
        MODE = self._old_mode

MODE = "sudo"

with mod_user():
    print MODE  # print : user.

print MODE  # print: sudo.

mod_user()
print MODE   # print: user.
于 2011-08-08T21:23:17.287 に答える
2

簡単な方法:

from contextlib import contextmanager
@contextmanager
def mode_user():
    global MODE
    old_mode = MODE
    MODE = "user"
    yield
    MODE = old_mode

の同上mode_sudo()。詳細については、ドキュメントを参照してください。__enter__これは実際には、「実装するクラスを定義する」全体のショートカットです__exit__

于 2011-08-08T21:09:08.163 に答える