如何在传递参数或说条件匹配时使用装饰器修饰函数

时间:2017-07-16 10:04:41

标签: python python-decorators

这是带参数的简单装饰器:

app.py

from __future__ import print_function
import time

def newdecorator(arg1):
    def benchmarking(funct):
        #The argument is accessible here
        print("this is the value of argument",arg1)
        def timercheck(*args, **kwarg):
            starttime=time.time()
            print("starting time",time.time())
            funct(*args, **kwarg)
            print("TOTAL TIME TAKEN ::",time.time()-starttime)
        return timercheck
    return benchmarking

#passing value to the decorators with arguments
@newdecorator('arg value')
def tara():
    print("hellow testing")

if __name__=="__main__":
    tara()

装饰者运作良好。它用一种功能来装饰功能,以显示开始时间和它所用的时间。

我想要实现的目标: 我希望有条不紊地实现装饰器。

  •   

    当用户运行app.py时,请不要实现装饰器

  •   

    用户运行app.py -t,而不是希望实现装饰器

我将使用argparse模块进行参数解析,这不是一个大问题,我想知道如何使装饰器有条件地工作。

4 个答案:

答案 0 :(得分:1)

@decorator语法只是语法糖。在幕后,所有发生的事情都是以装饰函数作为参数调用装饰器。

所以你可以在没有装饰器的情况下定义你的函数,然后在满足条件的情况下应用装饰器:

def tara():
    print("hellow testing")

if script_called_with_t_flag:
    tara = newdecorator('arg value')(tara)

答案 1 :(得分:1)

您还可以在模块或其他名称空间中使用全局变量,但这可能仅在您希望将此状态用于其他名称时才有用。拥有配置装饰器行为的应用程序设置并不罕见。

import time

TIMING_ENABLED = True


def newdecorator():
    def benchmarking(funct):
        def timercheck(*args, **kwarg):
            if TIMING_ENABLED:
                starttime = time.time()
                print("starting time", time.time())
            funct(*args, **kwarg)
            if TIMING_ENABLED:
                print("TOTAL TIME TAKEN ::", time.time() - starttime)
        return timercheck
    return benchmarking

# passing value to the decorators with arguments


@newdecorator()
def tara():
    print("hellow testing")


if __name__ == "__main__":
    TIMING_ENABLED = False
    tara()

将条件检查放在timercheck函数中非常重要,因为较低的范围在模块初始化期间执行(执行main()之前),我们将无法获得设置TIMING_ENABLED变量。

如果你只是希望这是一个开/关的东西,那么@ Rawing的答案是要走的路。

由于您不需要此特定装饰器的任何参数,您也可以简化它。我们应用没有()的装饰器,可以放弃一级嵌套。另外我们将functools.wraps装饰器添加到timecheck,所以这个函数看起来像python的tara函数。 (请参阅main中的其他打印件),因为装饰器实际上将tara函数替换为timecheck

from __future__ import print_function
import time
from functools import wraps

TIMING_ENABLED = True

def newdecorator(funct):
    @wraps(funct)
    def timercheck(*args, **kwarg):
        if TIMING_ENABLED:
            starttime=time.time()
            print("starting time",time.time())
        funct(*args, **kwarg)
        if TIMING_ENABLED:
            print("TOTAL TIME TAKEN ::",time.time()-starttime)
    return timercheck

@newdecorator
def tara():
    """Docs for tara function"""
    print("hellow testing")

if __name__=="__main__":
    TIMING_ENABLED = True
    print(tara.__name__, tara.__doc__)
    tara()

您随时可以移除@wraps(funct)行,看看main函数的tara将以不同的方式打印出来。

答案 2 :(得分:1)

您可以使用sys模块在Windows命令行

中使用参数运行Python脚本

使用 python app.py True 在终端中运行此代码以启用装饰器和禁用装饰器 python app.py python app.py False

function exportAsPdf(submittedBy) {
  var file = Drive.Files.get('1w5kqFmt1yclKVDdasujf-moxjX3QOVsyDyP7DIcF2u0');
  var url = file.exportLinks['application/pdf'];
  var token = ScriptApp.getOAuthToken();
  var response = UrlFetchApp.fetch(url, {
    headers: {
      'Authorization': 'Bearer ' +  token
    }
  });

 MailApp.sendEmail({ 
      to:Session.getActiveUser().getEmail(),
      subject:"Charts for Rent Analyser",
      htmlBody: "PFA",
      attachments:[response.getBlob().setName("Charts for Rent Analyser.pdf")],
     });  
}

答案 3 :(得分:0)

执行此操作的一种方法是仅在使用-t调用脚本时有条件地应用装饰器,否则不执行任何操作:

import time

script_called_with_t = True

def newdecorator(arg1):
    if script_called_with_t:
        def benchmarking(funct):
            #The argument is accessible here
            print("this is the value of argument",arg1)
            def timercheck(*args, **kwarg):
                starttime=time.time()
                print("starting time",time.time())
                funct(*args, **kwarg)
                print("TOTAL TIME TAKEN ::",time.time()-starttime)
            return timercheck
        return benchmarking
    else:
        return lambda funct: funct

#passing value to the decorators with arguments
@newdecorator('arg value')
def tara():
    print("hellow testing")

if __name__ == "__main__":
    TIMING_ENABLED = False
    tara()