【问题标题】:time calculation decorator with flask-restplus使用 flask-restplus 的时间计算装饰器
【发布时间】:2020-03-03 07:37:57
【问题描述】:

我正在使用flask 和flask-restplus 编写一个webapi。我创建了一个装饰器来计算执行 api 调用的时间。

import time

class TimeCalculateDecorator:

    def __init__(self, func): 
        self.function = func 

    def __call__(self,*args, **kws): 
            ts = time.time()
            result = self.function(*args, **kws)
            te = time.time()
            print('func:%r args:[%r, %r] took: %2.4f sec' % \
              (self.function.__name__, args, kw, te-ts))
            return result

这就是我使用它的方式......

class MultipleEmp_controller(Resource):


    @inject
    def __init__(self,api, dataservice:DataServiceBase):
        self.service = dataservice

    @TimeCalculateDecorator
    def get(self):
        """Get Request for version 1"""
        emp_schema = EmployeeSchema(many=True)
        emps = emp_schema.dump(self.service.getemployees())
        return emps

当装饰器调用上面的控制器方法并发现 self 参数从那里丢失时,问题就出现了。这是确切的错误消息...

"get() missing 1 required positional argument: 'self'",

我尝试了谷歌,但没有运气。

我尝试了像下面这样的简单方法装饰器...

def timeit(method):
    def timed(*args, **kw):
        ts = time.time()
        result = method(*args, **kw)
        te = time.time()
        print('func:%r args:[%r, %r] took: %2.4f sec' % \
          (method.__name__, args, kw, te-ts))
        return result
    return timed

这一切都很好。当我将它作为类而不是方法时,问题就出现了。

【问题讨论】:

标签: python flask flask-restplus


【解决方案1】:

您的 TimeCalculateDecorator 正在调用包装函数,但未传入对正确 MultipleEmp_controller 实例的引用。

我不确定如何使用纯装饰器正确引用,但这里有一种在类初始化期间实现装饰方法的方法:

import time

class TimeCalculateDecorator:
    def __init__(self, func, **kwargs): 
        self.function = func 

    def __call__(self,*args, **kws): 
            ts = time.time()
            result = self.function(*args, **kws)
            te = time.time()
            print('func:%r args:[%r, %r] took: %2.4f sec' % \
              (self.function.__name__, args, kws, te-ts))
            return result

class MultipleEmp_controller(object):
    def __init__(self, *args, **kwargs):
        self.get = TimeCalculateDecorator(self.get)
        return  

    def get(self):
        """Get Request for version 1"""
        print('called')
        return 


if __name__ == '__main__':
    x = MultipleEmp_controller()
    x.get()

另外,值得回顾一下answer

【讨论】:

  • 谢谢伊恩...我已经尝试过了,它正在工作。但正如你也提到它不是纯装饰器,我希望它只使用装饰器
猜你喜欢
  • 2016-01-02
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 2015-10-27
  • 2018-12-30
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多