6

PythonライブラリFabricを使用して、リモートサーバーのメンテナンスを行っています。コマンドをステートメントと組み合わせてラップしない限り、Fabricはリモートコマンドとローカルコマンドへのすべての応答を自動的に出力します。そのように、ローカルマシンでは、

with settings(warn_only='true'):
    with hide('running', 'stdout', 'stderr', 'warnings'):
        output = local("uname -a", True)

またはリモートマシンでこのように:

with settings(warn_only='true'):
    with hide('running', 'stdout', 'stderr', 'warnings'):
        output = run("uname -a")

私は長くて複雑なタスクを書いていますが、ステートメントを使ってこれら2つを何度も繰り返しています。その繰り返しを防ぐために、_mute()という関数を書きたいと思います。それは私にこのようなことをさせてくれるでしょう:

def _mute(fabric_cmd, args):
    with settings(warn_only='true'):
        with hide('running', 'stdout', 'stderr', 'warnings'):
            output = fabric_cmd(args)
    return output

def some_remote_task():
    # Run a remote task silently
    _mute(remote, 'uname -a')

def some_local_task():
    # Run a local task silently
    _mute(local, 'uname -a', True)

私はいくつかの解決策を調べましたが、「eval」が私のためにこれを行うことができることを知っています。しかし、私がevalについて読んだすべてのページは、セキュリティの問題のために、ほとんどの場合、それは悪い考えであることを示唆しています。パーシャルを調べましたが、_mute関数で引数を呼び出し可能にする方法がわかりませんでした。私がここで見逃しているより高いレベルのPythonの概念があると思います。これを行うためのPythonの方法は何ですか?あなたが提供できるかもしれないどんな方向にも感謝します。

4

1 に答える 1

11

より良い解決策は、独自のコンテキスト マネージャーを作成することです。最も簡単な方法は、contextlib.contextmanagerデコレータを使用することです。

from contextlib import contextmanager

@contextmanager
def _mute():
    with settings(warn_only='true'):
        with hide('running', 'stdout', 'stderr', 'warnings'):
            yield

次に_mute、コンテキスト マネージャーとして使用します。

def some_remote_task():
    # Run a remote task silently
    with _mute():
        output = remote("uname -a")

これは、2 つの大きなコンテキスト マネージャー行を再入力するよりもはるかにコンパクトで読みやすく、同じコンテキストで複数のコマンドを実行できるという利点があります。

あなたの質問については; *args次の構文を使用して、特定の関数に任意の引数を簡単に適用できます。

def _mute(fabric_cmd, *args):
    with settings(warn_only='true'):
        with hide('running', 'stdout', 'stderr', 'warnings'):
            return fabric_cmd(*args)

def some_remote_task():
    # Run a remote task silently
    output = _mute(remote, 'uname -a')

*args と **kwargs?を参照してください。*args任意の引数リストのトリックの詳細については。

于 2012-09-03T16:54:54.463 に答える