1

p4で最後に同期された変更リストを取得するためのpythonメソッドがあるとしましょう。(質問自体はp4とは関係なく、基本的なpythonの質問のみです)

def get_last_synced_changelist(p4port, client_name, p4 = None):
    with P4Connection(p4port) as p4:
        last_change_list = p4.run_changes("-m1", "@%s" % client_name)
        if last_change_list:
            return last_change_list[0]["change"]
        else:
            return None

このメソッドの呼び出し元は、文字列である p4port を提供するか、p4 オブジェクト自体を提供することができます。私の要件は、「p4」オブジェクトが提供されている場合、withコンテキストなしでメソッド本体を実行したいということです。つまり、 p4 で呼び出されたenterまたはexitメソッドは必要ありません。これは、p4 オブジェクトを閉じる/入力する責任が呼び出し元にあるためです。p4 オブジェクトが指定されていない場合は、p4port 文字列を使用してこのプログラムで with 構文を構築する必要があります。

このメソッドを構築する最良の方法を誰か教えてもらえますか? 身体の変化はなるべく少なくしたい。基本的に次のようなもの

p4 or with P4Connection(p4port) as p4:
   p4.run_changes(...)

しかし、最適な構文が何であるかはわかりません。

4

3 に答える 3

2

直接可能でwithはなく、複合ステートメントであり、このような式に埋め込むことはできません。ただし、関数がリソースの「借用」もサポートしているという事実を利用できます。

def get_last_synced_changelist(p4port, client_name, p4 = None):
    if p4 is None:
        with P4Connection(p4port) as p4:
            return get_last_synced_changelist(p4port, client_name, p4)
    last_change_list = p4.run_changes("-m1", "@%s" % client_name)
    if last_change_list:
        return last_change_list[0]["change"]
    else:
        return None

このアプローチは、2 つのパスに別々の関数がある場合でも機能します (この例でp4portは、既存のパスが渡されたときに明らかに使用されていないため、これは理にかなっている可能性がありますP4Connection)。

于 2013-08-05T12:35:58.917 に答える
0

Python 2 では、おそらく独自のコンテキスト マネージャーを作成する必要があります。@glglgl の回答に示されているダミーのマネージャー、または P4Connection のオプションの作成をまとめたものです。

import contextlib

@contextlib.context_manager
def p4_context(p4port, p4=None):
    p4 is None:
        with P4Connection(p4port) as p4:
            yield p4
    else:
        yield p4

def get_last_synced_changelist(p4port, client_name, p4 = None):
    with p4_context(p4port, p4) as p4:
        last_change_list = p4.run_changes("-m1", "@%s" % client_name)
        if last_change_list:
            return last_change_list[0]["change"]
        else:
            return None

Python 3.3 以降を使用している場合は、代わりにすばらしい新しいcontextlib.ExitStackクラスを使用できます。

import contextlib

def get_last_synced_changelist(p4port, client_name, p4 = None):
    with contextlib.ExitStack() as stack:
        if p4 is None:
            p4 = stack.enter_context(P4Connection(p4port))

        last_change_list = p4.run_changes("-m1", "@%s" % client_name)
        if last_change_list:
            return last_change_list[0]["change"]
        else:
            return None
于 2013-08-05T13:00:08.397 に答える