提示:在看python 一些包的源码时经常会看到 函数或者是类声明的上一行出现“@” 那么这个的作用是什么呢?:
代码如下:
data = [i for i in range(10 ** 7)]
def foo(func):
def getTime():
start = time.time()
func()
end = time.time()
print("运行时间 : ",end - start)
return getTime //返回一个callable
@foo
def main():
a = []
for i in data:
a.append(i * 2)
这段程序可用来计算函数的运行时间
装饰器可以将一个函数传入另一个函数,再通过另一个函数返回一个函数最后我们调用的时候使用的就是返回得到的这个函数。
@foo
def circulation():
a = []
for i in data:
a.append(i * 2)
@foo
def listMethod():
a = [i*2 for i in data]
@foo
def mapMethod():
# 需要转化成list 不然时间为0 ,map得到得到是一个可迭代的对象
a = list(map(lambda x:x * 2,data))
得到的结果 列表推导式 < for 循环 < map。(不过可能在不同的场景下的运行速率会有所不同,之前看到map方法的运行速率是排在中间的)
在上面的例子中我们不好看出来输出的结果到底对应的是哪个,可以通过装饰器传参的形式实现。
# 装饰器部分的函数
def decoration(method):
def foo(func):
def getTime():
start = time.time()
func()
end = time.time()
print(f"{method}运行时间 : ",end - start)
return getTime
return foo
@decoration("circulation")
def circulation():
a = []
for i in data:
a.append(i * 2)
@decoration("listMethod")
def listMethod():
a = [i*2 for i in data]
@decoration("mapMethod")
def mapMethod():
# 需要转化成list 不然时间为0 ,map得到得到是一个可迭代的对象
a = list(map(lambda x:x * 2,data))
代码如下(示例):
class Animal():
caration = "动物"
def __init__(self, func) -> None:
func.caration = self.caration
self.c1 = func
//magic方法可以让类也变成callable 即让类可以像函数一样被调用,可以用来修改类内的变量
def __call__(self, *args: Any, **kwds: Any) -> Any:
print("调用")
return self
@Animal
class Dogs():
def worfe():
print("I am a dog")
if __name__ == '__main__':
a = Dogs()
print(a.caration)
print(type(a))
输出的结果为:
可以通过第三个输出,可以推断出经过类装饰器后Dogs类变成了一个Animal类。
下面将增加Animal类中的方法
class Animal():
caration = "动物"
def __init__(self, func) -> None:
func.caration = self.caration
self.worfe = func.worfe
self.c1 = func
def __call__(self, *args: Any, **kwds: Any) -> Any:
print("调用")
return self
@Animal
class Dogs():
def worfe():
print("I am a dog")
if __name__ == '__main__':
a = Dogs()
a.worfe()
装饰器的主要的思想主要就是将一个func或者是class传递到另一个func或者class,并由此修改原函数或者类的一些功能。