【问题标题】:python decorators not taking the value from constant passedpython装饰器没有从传递的常量中获取值
【发布时间】:2017-12-24 16:32:02
【问题描述】:

report.py

if __name__ == "__main__":    
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, description = "CHECK-ACCESS REPORTING.")
    parser.add_argument('--input','-i', help='Filepath containing the Active Directory userlist')
    parser.add_argument('--timestamp', '-t', nargs='?',const="BLANK", help='filepath with environement varible set')        
    args, unknownargs = parser.parse_known_args(sys.argv[1:])

    timestampchecker(args.timestamp)
    #checking the value of cons.DISPLAYRESULT is TRUE        
    main()

时间戳检查功能:

def timestampchecker(status):
    """ Check if the timestamp is to display or not from command line"""
    if status is not None:
        cons.DISPLAY_TIME_STAMP = True

此函数检查用户是否设置了 -t 参数。如果已设置,我已将一个名为 cons.DISPLAYRESULT 的常量定义为 true。

该函数运行良好,并将常量值变为 True。 但是在主要功能中,我已经实现了这个装饰器,它不是取真值而是假的

timer.py

def benchmarking(timestaus):
    def wrapper(funct):
        def timercheck(*args, **kwarg):
            if timestaus is True:
                starttime=time.time()
            funct(*args, **kwarg)
            if timestaus is True:
                print('Time Taken:',round(time.time()-starttime, 4))
        return timercheck
    return wrapper

我在report.py 的main() 方法中用上面的装饰器装饰了一些方法。例如,这是在 report.py 中使用并使用上述装饰器进行装饰的类

class NotAccountedReport:

    def __init__(self, pluginoutputpath):
        """ Path where the plugins result are stored need these files"""

        self.pluginoutputpath = pluginoutputpath

    @benchmarking(cons.DISPLAY_TIME_STAMP)
    def makeNotAccountableReport():
        #some functionality

这里我将常量值传递给参数装饰器 测试时,虽然在调用之前转换为 True 是假的 因此装饰器没有被实现。问题出在哪里 想不通

【问题讨论】:

  • 这是一个微不足道的观点,但也许我不理解你的最后一段。当您说“我已将常量值传递给参数装饰器”时,您的意思是 @benchmarking(const)?那么const is Truebool(const) is True会有不同的结果。
  • 我的意思是说我已经定义了常量并且那个值是装饰器被传递的。装饰器仅在该值设置为 True 时运行。但是正在发生的事情是认为常量值更改为 True 装饰器首先被加载并取而代之的是 False

标签: python python-2.7 python-decorators


【解决方案1】:

您没有发布完整的最小可验证示例,因此可能还有其他内容,但如果您的意思是在调用 NotAccountedReport().makeNotAccountableReport() 时您没有打印出“所用时间”,那么这真的不足为奇 - benchmarking 装饰器在定义函数时应用(当导入模块时),远在执行 if __name__ == '__main__' 子句之前,所以那时 cons.DISPLAY_TIME_STAMP 还没有被你的命令行参数更新。

如果您想要一个运行时标志来激活/停用装饰器的行为,显而易见的解决方案是在装饰器中检查 cons.DISPLAY_TIME_STAMP 而不是将其作为参数传递,即:

def benchmarking(func):
    def timercheck(*args, **kwarg):
        if cons.DISPLAY_TIME_STAMP:
           starttime=time.time()
        result = func(*args, **kwarg)
        if cons.DISPLAY_TIME_STAMP:
            logger.debug('Time Taken: %s',round(time.time()-starttime, 4))
        return result  
    return timercheck


class NotAccountedReport(object):
    @benchmarking
    def makeNotAccountableReport():
        #some functionality

【讨论】:

  • 这正是问题所在。那么可以为解决方案做些什么。 cons.DISPLAY_TIME_STAMP 已更新,但正如您所提到的,装饰器在函数在 `if name__=='__main' 中被调用之前正在取值。任何解决方案
  • 嗯,这似乎很明显:不要将cons.DISPLAY_TIME_STAMP 作为参数传递给您的装饰器,直接检查它,参见我编辑的答案。
猜你喜欢
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 2012-02-29
  • 2022-08-19
  • 2020-01-02
  • 2022-11-09
  • 2012-05-31
  • 1970-01-01
相关资源
最近更新 更多