手机购物网站 设计,建设各网站需要多久,seo职位,wordpress需要的插件吗上下文管理(为加法函数计时)为加法函数计时使用装饰器显示该函数的执行时长使用上下文管理显示该函数的执行时长装饰器实现import timeimport datetimefrom functools import wrapsdef logger(fn):wraps(fn) # wraps(fn)(wrapper)def wrapper(*args, **kw):start datetime.dat…上下文管理(为加法函数计时)为加法函数计时使用装饰器显示该函数的执行时长使用上下文管理显示该函数的执行时长装饰器实现import timeimport datetimefrom functools import wrapsdef logger(fn):wraps(fn) # wraps(fn)(wrapper)def wrapper(*args, **kw):start datetime.datetime.now()ret fn(*args, **kw)delta (datetime.datetime.now() - start).total_seconds()print(delta)return retreturn wrapperloggerdef add(x, y):time.sleep(2)return x y上下文实现最简单实现增加__call__用法import timeimport datetimeclass TimeIt:def __init__(self, fn):self.fn fndef __enter__(self):self.start datetime.datetime.now()return selfdef __exit__(self, exc_type, exc_val, exc_tb):self.delta (datetime.datetime.now() - self.start).total_seconds()print(self.delta)def __call__(self, *args, **kwargs):ret self.fn(*args, **kwargs)return retdef add(x, y): This is addtime.sleep(2)return x ywith TimeIt(add) as foo:print(foo(3,4))需要增加初始化方法为下面__call__使用__enter__方法返回self是为了有了__call__方法以后可以这样使用with TimeIt(add) as foo: foo(3,4)因为有了__call__后实例变成可调用而foo就是实例化后的实例TimeIt(add)是将add函数名作为形参传进去改成装饰器import timeimport datetimeclass TimeIt:def __init__(self, fn):self.fn fndef __enter__(self):self.start datetime.datetime.now()return selfdef __exit__(self, exc_type, exc_val, exc_tb):self.delta (datetime.datetime.now() - self.start).total_seconds()print(self.delta)def __call__(self, *args, **kwargs):print(call)ret self.fn(*args, **kwargs)return retTimeIt # add TimeIt(add)def add(x, y): This is addtime.sleep(2)return x y# 上下文用法# with TimeIt(add) as foo:# print(foo(3,4))print(add(5,6))print(add.__doc__)print(add.__dict__)print(add.__name__)装饰器用法很简单直接在add函数上加个TimeIt这是由于TimeIt等价于add TimeIt(add)把add函数名作为实参传入到TimeIt类中就相当于为add函数加了一个类封装的功能或属性而这个时候我们发现用装饰器实现后直接走的是__call__方法中的语句块而上下文没有执行(因为没有用with..as语句)也就是说要么用with..as语句要么用装饰器方法这是两个方法(用with..as语句执行装饰器方法这样比较繁琐重复计算因题而异)但是如何解决文档字符串的问题怎么把add函数的配置信息也弄过来(看__doc__和__dict__就可以知道)解决文档字符串问题方法1把函数对象的文档字符串赋给类class TimeIt:def __init__(self, fn):self.fn fnself.__doc__ self.fn.__doc__self.__name__ self.fn.__name__self.__dict__ self.fn.__dict__方法2使用functools.wraps函数最终完整版import timeimport datetimefrom functools import wrapsclass TimeIt:This is Classdef __init__(self, fn):self.fn fn# 把函数对象的文档字符串赋给类# self.__doc__ self.fn.__doc__# self.__name__ self.fn.__name__# wraps wraps(fn)(wrapper)wraps(fn)(self) # wraps用法# def __enter__(self):# self.start datetime.datetime.now()# return self# def __exit__(self, exc_type, exc_val, exc_tb):# self.delta (datetime.datetime.now() - self.start).total_seconds()# print(self.delta)def __call__(self, *args, **kwargs):print(call)self.start datetime.datetime.now()ret self.fn(*args, **kwargs)delta (datetime.datetime.now() - self.start).total_seconds()print(delta)return retTimeIt # add TimeIt(add)def add(x, y): This is addtime.sleep(2)return x y# 上下文用法# with TimeIt(add) as foo:# print(foo(3,4))print(add(5,6))print(add.__doc__)print(add.__dict__)print(add.__name__)print(type(add))第15行的用法wraps(fn)(self)是根据这个wraps wraps(fn)(wrapper)来的wraps是带参装饰器fn就是带参wrapper是传入的实参简单来说wraps wraps(fn)(wrapper)就是把fn的配置信息赋值给wrapper所以wraps(fn)(self)就是把fn的配置信息赋值给实例(self就是实例化后的实例)本文来自投稿不代表Linux运维部落立场如若转载请注明出处http://www.178linux.com/88584