3

次のように、すべての操作を実行する前に、値をチェックするなどの繰り返しを行う関数またはメソッドがあるとします。

def myfunc():
    if mybool:
        do_operation_1()
    else:
        return

    if mybool:
        do_operation_2()
    else:
        return

    ...

これらのチェックは繰り返し行われ、多くの時間とキーボード スプリングを浪費することになります。

たとえば、操作関数を制御do_operation_Nできる場合は、ブール値をチェックするもので関数を装飾できます。

しかし、個々の操作を制御できない場合はどうでしょdo_operation_Nうか? 関数またはメソッドの各行に対して同じチェックを実行したい場合、各操作行に明示的に書き込まずに「挿入」する方法はありますか? たとえば、次のことができるデコレータ マジックはありますか?

def magic_decorator(to_decorate):
    def check(*args, **kwargs):
        for call in to_decorate: #magic
            if mybool:
                to_decorate.do_call(call) #magic
            else:
                return #or break, raise an exception, etc
    return check

@magic_decorator
def myfunc():
    do_operation_1()
    do_operation_2()
    ...

これを実現する方法があれば、デコレータを使用するかどうかは気にしません。「関数/メソッドXのすべての行について、最初にYを実行してください」と言う方法が欲しいだけです。

上記のメソッドの「魔法の」例は、do_call私が求めているものの省略形ですが、個々の行の順不同の実行で深刻な問題が発生します (たとえば、関数の最初の行が変数の割り当てであり、その2 番目はその変数の使用であり、順不同で実行すると問題が発生します)。

明確にするために:関数の実行の行ごとの順序を外部から制御する機能は、私が達成しようとしているものではありません。理想的には、自然な実行順序で操作を実行するものを実装するだけです毎回myfunc何かをします。「何かをする」が「関数またはメソッドを呼び出す」(代入、ifチェックなどを除く)に限定される場合、それは問題ありません。

4

2 に答える 2

6

操作をシーケンスに保存してから、ループを使用します。

ops = (do_operation_1, do_operation_2, do_operation_3)

for op in ops:
    if mybool:
        op()
    else:
        return
于 2012-11-02T16:00:28.443 に答える
0

基本的に、装飾された関数からファイルと行番号を抽出し、関数を再度読み取り、AST にコンパイルし、AST にノードを挿入し、AST をコンパイルしてそれを関数として使用できます。

この方法は、非常に長い関数に使用できます。これは、上記のアプローチを使用している場合に問題になります。

于 2015-08-25T00:28:59.453 に答える