Python:我如何将其转换为装饰器

时间:2017-07-20 19:58:11

标签: python performance time

我不能为我的生活弄清楚如何把它变成装饰者。 任何帮助或示例都会很棒。

以下是代码

import datetime    

def time_func(function, *args, **kwargs):
  '''
  Add the execution time to a functions attributes 
  '''
  # Start the clock.
  start = datetime.datetime.now()
  # Execute the function and record the results.
  function_result = function(*args, **kwargs)
  # Calculate the elapsed time and add it to the function
  # attributes.
  function.elapsed = datetime.datetime.now() - start
  # Returned the function with the added elapsed attribute 
  return function_result

以下是使用示例

.. import datetime 
..  
..  
.. def time_func(function, *args, **kwargs): 
..   ''' 
..   Add the execution time to a functions attributes  
..   ''' 
..   # Start the clock. 
..   start = datetime.datetime.now() 
..   # Execute the function and record the results. 
..   function_result = function(*args, **kwargs) 
..   # Calculate the elapsed time and add it to the function 
..   # attributes. 
..   function.elapsed = datetime.datetime.now() - start 
..   # Returned the function with the added elapsed attribute  
..   return function_result 
..    
..  
.. def f(name): 
..   print name 
..    
.. time_func(f, 'foo') 
.. print f.elapsed 
.. 
foo
0:00:00.000115

3 个答案:

答案 0 :(得分:2)

装饰器只是一个接受函数并返回函数的函数。

import datetime

def time_func(function):
    # create a new function based on the existing one,
    # that includes the new timing behaviour
    def new_func(*args, **kwargs):
        # Start the clock.
        start = datetime.datetime.now()
        # Execute the function and record the results.
        function_result = function(*args, **kwargs)
        # Calculate the elapsed time and add it to the function
        # attributes.
        new_func.elapsed = datetime.datetime.now() - start
        # Returned the function with the added elapsed attribute 
        return function_result
    return new_func

用法:

@time_func
def f(name):
    print(name)

f('foo')
print(f.elapsed)
> foo
> 0:00:00.000045

查看functools.wraps以进一步改进装饰器。

答案 1 :(得分:1)

定义内部函数:

import datetime    

def time_func(function):
    '''
    Add the execution time to a functions attributes 
    '''
    def func(*args, **kwargs):
        start = datetime.datetime.now()
        function_result = function(*args, **kwargs)
        func.elapsed = datetime.datetime.now() - start
        return function_result
    return func

@time_func
def f(name):
    print name

答案 2 :(得分:0)

制作装饰器的常用方法是使用两个嵌套函数:

def time_func(function):
  def wrapper(*args, **kwargs):
      start = datetime.datetime.now()
      function_result = function(*args, **kwargs)
      wrapper.elapsed = datetime.datetime.now() - start
      return function_result
   return wrapper

此代码与原始代码之间唯一的主要内容(除了删除空间注释除外)是function由外部函数调用提供,而其他参数提供给包装函数。我们还需要将elapsed时间保存在wrapper函数而不是原始函数上(因为当你是一个装饰器时,原来将无法再访问原文。)