也就是说,get_function()返回的值x本身就是一个函数 。
尝试再次运行B和C行 。请注意,每次重复此过程时,返回的returned_function地址都是不同 。每次调用get_function都会生成新的returned function 。
d
因为x是函数,所以就可以调用它 。调用x就是调用returned_function的一个实例 。这里输出的是:
inside returned_function1也就是说,它打印字符串,并返回值1 。
回到时间问题
你现在仍然在看么?如此我们有了新的知识,那么我们如何解决我们的老问题?我建议我们创建一个函数,让我们调用它并称为time_this,它将接收另一个函数作为参数,并将参数函数封装在某些计时代码中 。有点像:
def time_this(original_function): # 1 def new_function(*args,**kwargs): # 2 before = datetime.datetime.now() # 3 x = original_function(*args,**kwargs) # 4 after = datetime.datetime.now() # 5 print("Elapsed Time = {0}".format(after-before)) # 6 return x # 7 return new_function() # 8我承认它有点疯狂,所以让我们一行一行的看下去:
1这只是time_this的原型 。time_this是一个函数就像任何其他函数一样,并且只有一个参数 。 2我们在内部定义一个函数time_this 。每当time_this执行时它都会创建一个新函数 。 3计时代码,就像之前一样 。 4我们调用原始函数并保留结果以供日后使用 。 5,6剩余的计时代码 。 7new_function必须像原始函数一样运行,因此返回存储的结果 。 8返回在time_this中创建的函数 。
现在我们要确保我们的函数是计时的:
def func_a(stuff): do_important_things_1() do_important_things_2() do_important_things_3()func_a = time_this(func_a) # <---------def func_b(stuff): do_important_things_4() do_important_things_5() do_important_things_6()func_b = time_this(func_b) # <---------def func_c(stuff): do_important_things_7() do_important_things_8() do_important_things_9()func_c = time_this(func_c) # <---------看看func_a,当我们执行时func_a = time_this(func_a)我们用time_this返回的函数替换func_a 。所以我们用一个函数替换func_A该函数执行一些计时操作(上面的第3行),将func a的结果存储在一个名为x的变量中(第4行),执行更多的计时操作(第5行和第6行),然后返回func_a返回的内容 。换句话说func_a,仍然以相同的方式调用并返回相同的东西,它也只是被计时了 。是不是感觉很整洁?
介绍装饰器我们所做的工作很好,而且非常棒,但是很难看,非常难读懂 。所以Python可爱的作者给了我们一种不同的,更漂亮的写作方式:
@time_thisdef func_a(stuff): do_important_things_1() do_important_things_2() do_important_things_3()完全等同于:
def func_a(stuff): do_important_things_1() do_important_things_2() do_important_things_3()func_a = time_this(func_a)这通常被称为语法糖 。@没有什么神奇的 。这只是一个已达成一致的惯例 。沿着这条路上的某个地方决定了 。
总结
装饰器只是一个返回函数的函数 。如果这些东西看起来非常的 - 那么请确保以下主题对你有意义然后再回到本教程:
- Python函数
- 范围
- Python作为第一类对象(甚至可以查找lambda函数,它可能使它更容易理解) 。
- 如装饰类:
- 具有更多参数的装饰器,例如:
下面就是我要介绍的高级装饰器的主题 。
装饰器的高级用法介绍
下面这些旨在介绍装饰器的一些更有趣的用法 。具体来说,如何在类上使用装饰器,以及如何将额外的参数传递给装饰器函数 。
装饰者与装饰者模式
装饰器模式是一种面向对象的设计模式,其允许动态地将行为添加到现有的对象当中 。当你装饰对象时,你将以独立于同类的其他实例方式扩展它的功能 。
Python装饰器不是装饰器模式的实现 。Python装饰器在定义时向函数和方法添加功能,它们不用于在运行时添加功能 。装饰器模式本身可以在Python中实现,但由于Python是Duck-teped的,因此这是一件非常简单的事情 。
一个基本的装饰
这是装饰器可以做的一个非常基本的例子 。我只是把它作为一个参考点 。在继续之前,请确保你完全理解这段代码 。
def time_this(original_function):def new_function(*args,**kwargs): import datetimebefore = datetime.datetime.now()x = original_function(*args,**kwargs)after = datetime.datetime.now()print ("Elapsed Time = {0}".format(after-before))return xreturn new_function @time_thisdef func_a(stuff): import time time.sleep(3)func_a(1)
推荐阅读
- 如何用Python操作数据库?
- php加速器之opcache
- 华为NE40E-X16特性,NE40E-X16功能,全业务路由器
- 中国第一个目标飞行器和空间站是
- 出门旅游的三大神器,有人总嫌它们太麻烦,驴友:尽量都带上
- 空调器几种关键零部件介绍
- 净水器产出的水都可以被直接饮用吗?
- 功夫茶器具与标准的功夫茶艺
- 陆羽用的茶器赏析
- 手机边充电边玩,消耗的电量是来自电池还是充电器呢?