2016-12-19 3 views
-2

私はこのコードを "Learning Python"セクションのデコレータから入手したことに問題があります。このPythonデコレータコードを理解する

なぜこのコードはresultの変数値を2回ではなく1回返しますか? "max_result"に1回、 "measure"にもう1回、結果変数の量を2回返しました。ここにコードです:

from time import sleep, time 
from functools import wraps 

def measure(func): 
    @wraps(func) 
    def wrapper(*args, **kwargs): 
     t = time() 
     result = func(*args, **kwargs) 
     print(func.__name__, 'took:', time() - t) 
     return result 
    return wrapper 

def max_result(func): 
    @wraps(func) 
    def wrapper(*args, **kwargs): 
     result = func(*args, **kwargs) 
     if result > 100: 
      print('Result is too big ({0}). Max allowed is 100.' 
        .format(result)) 
     return result 
    return wrapper 

@measure 
@max_result 
def cube(n): 
    return n ** 3 

print(cube(2)) 
print(cube(5)) 

ここで出力は、私たちは2つの8つまたは2つの125を取得しないでください?

>>> print(cube(2)) 
cube took: 8.106231689453125e-06 
8 
>>> print(cube(5)) 
Result is too big (125). Max allowed is 100. 
cube took: 5.91278076171875e-05 
125 
>>> 
+0

なぜあなたは2つの8つを取得する必要があると思いますか? – mgilson

+0

印刷ステートメントは3つしかなく、それぞれ最大で1回実行されます。 –

+0

boock: "2回目の呼び出しでは結果が125になるため、エラーメッセージが出力され、結果は が返され、それが計測時間になります。実行時間をもう一度表示します。 最後に、その結果(125)。 私たちはその結果を2回返します。 – ali

答えて

4

デコレータはをを連鎖されています。元のcube()ファンクションは、max_resultデコレータによってラップされ、その装飾の結果は、measureで装飾されました。

のでcube()の戻り値はmax_result()wrapper()によって取り込まれ、その関数の結果が呼び出し側に返される前にmeasure()wrapper()によって取られます。

すべてのデコレータはあなたを与えるだろう解明:

  • measure_wrapper(2)、記録t = time()をして
    • max_result_wrapper(2)を呼び出し、直接
        呼び出す:だから cube(2)が生成する呼び出し

        def measure_wrapper(*args, **kwargs): 
            t = time() 
            result = max_result_wrapper(*args, **kwargs) 
            print(func.__name__, 'took:', time() - t) 
            return result 
        
        def max_result_wrapper(*args, **kwargs): 
            result = original_cube(*args, **kwargs) 
            if result > 100: 
             print('Result is too big ({0}). Max allowed is 100.' 
               .format(result)) 
            return result 
        
        def original_cube(n): 
            return n ** 3 
        
        cube = measure_wrapper 
        

      • 戻っ2 ** 3が偽ので
      • 戻りwhichis、max_result_wrapper()呼び出しがかかった8
    • プリント時間と
    • 戻り8 > 1008
  • テストで
  • original_cube(2)8
+0

答えをありがとう、私は今完全に理解しています。 – ali