Fork me on GitHub

Python装饰器

Python装饰器

之前对装饰器的理解就一句话:对一个函数,对其不做任何改变的条件下,增加新的功能。个人觉得,这句话并没有什么毛病,但是实际在代码中体现的时候,各种内函数,外函数的,理解起来还是比较晕,尤其是带参数的装饰器。。。

  • 先看普通装饰器

    1. 函数test1和函数test2是原始代码:

       def test1():
       	time.sleep(2)
       	print('in the T1')
      
       def test2(name,age):
       	time.sleep(1)
       	print('name is %s and age is %s'%(name,age))
      
       test1()
       test2('ZZl',25)
      
    2. 现在的需求是给这两个函数加一个功能,分别计算这两个函数执行的时间。假设函数test1和函数test2已经被其他地方调用,所以对其增加新的功能就不能改变他们的调用方式,也不能改变这两个函数的内部代码,所以这里用上了装饰器。。。

       import time
       #要增加的功能,将其定义为一个名为timer的函数
       def  timer(fun):
       	def deco(*args,**kwargs):
       		start_time = time.time()    	#开始时间
       		fun(*args,**kwargs)
       		stop_time = time.time()			#结束时间
       		print(stop_time - start_time)	#打印时间差
       	return deco
      
       @timer               #test1 = timer(test1)   覆盖之前的test1()
       def test1():
       	time.sleep(2)
       	print('in the T1')
       @timer               #test1 = timer(test1)   覆盖之前的test2()
       def test2(name,age):
       	time.sleep(1)
       	print('name is %s and age is %s'%(name,age))
      
      
       test1()
       test2('ZZl',25)
      
    3. 上面代码实现的原理就是将函数test1和函数test2作为参数传递给timer函数。

  • 带参数的装饰器

    1. 价格参数,将之前的@timer改成@timer(cs1),为一个cs1参数传递给timer()

       import time
       #要增加的功能,将其定义为一个名为timer的函数
       def  timer(canshu):
       	def deco(fun,*args,**kwargs):
       		start_time = time.time()    	#开始时间
       		fun(*args,**kwargs)
       		stop_time = time.time()			#结束时间
       		print(stop_time - start_time)	#打印时间差
       	return deco
      
       
       @timer(cs1)
       def test2(name,age):
       	time.sleep(1)
       	print('name is %s and age is %s'%(name,age))
      

      test2('ZZl',25)

    2. 解释器在执行代码的时候,在遇到@timer(cs1)这句时,做的操作是timer(cs1),开始跟语法糖 @ 没任何关系,先执行timer(cs1),也就跟调用timer(canshu)这个函数一样,只不过是实参是cs1,执行结果得到的是:deco(因为timer(canshu)函数return deco)。第二部就是@deco,@deco就跟上面的普通装饰器一样了,就是将test2作为参数传递给deco函数执行。。。

      解释器解释到这行: @timer(cs1)

      第一步执行: timer(cs1) ----->返回 deco

      第一步结果: @deco

      第二步执行: @deco

      第二步执行过程: deco(test2(name,age))

3.有助于理解Flask的路由方法...

posted @ 2018-09-19 01:42  MisterZZL  阅读(93)  评论(0编辑  收藏  举报