装饰器(函数)

闭包

1.作用域L_E_G_B(局部、内嵌、全局...):

1 x=10#全局
2
3 def f():
4     a=5 #嵌套作用域
5     def inner():
6         count = 7 #局部变量
7         print a
8         return 1

从内往外寻找 a 。

2.高阶函数

a.函数名可以作为参数输入

b.函数名可以作为返回值

3.闭包

 1 def outer():
 2     x=10
 3     def inner(): #条件1 inner是内部函数
 4         print(x) #条件2 外部环境的一个变量
 5
 6     return inner #结论: 内部函数inner就是一个闭包
 7
 8 outer()()#调用inner
 9 #同上
10 f = outer()#获得inner
11 f()#调用执行inner
12
13 #不能直接调用inner,因为inner为局部变量,全局无法调用

执行结果

10
10

Process finished with exit code 0

第10行,获得inner变量,第11行执行inner函数,而执行inner函数时(在外部执行),其中x变量既不属于inner函数内部变量,也不属于全局变量,按理应该报错却没报错,这种现象称为闭包。

定义:如果在一个内部函数里,对在外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。

在内部函数里(inner函数中),对在外部作用域的变量(x)进行引用(print),那么内部函数(inner)就被认为是闭包。

装饰器

 1 import time
 2
 3 def foo():
 4     print("foo.....")
 5     time.sleep(2)
 6
 7 def bar():
 8     print("bar.....")
 9     time.sleep(3)
10
11 def show_time(f): #函数名作参数
12     start = time.time()
13     f()
14     end = time.time()
15     print("spend %s" % (end - start))
16
17
18 show_time(bar)

函数名作参数,减少重复代码。

执行结果:

bar.....
spend 3.0022976398468018

Process finished with exit code 0

但是以上方法改变了调用方式,加上所需时间功能后,不是直接用foo,而是用show_time,这样对所有使用foo函数的代码都需修改,违背了封闭开放原则。

 1 import time
 2
 3 def foo():
 4     print("foo.....")
 5     time.sleep(2)
 6
 7 def bar():
 8     print("bar.....")
 9     time.sleep(3)
10
11 def show_time(f): #函数名作参数 ,装饰器
12     def inner():
13         start = time.time()
14         f()
15         end = time.time()
16         print("spend %s" % (end - start))
17     return inner
18
19 foo = show_time(foo)
20 foo()

show_time即为装饰器,inner函数为闭包,f函数名变量即为外部作用域变量。

执行结果:

foo.....
spend 2.00213360786438

Process finished with exit code 0

但是以上方法还需要自己赋值,不够简便、优雅。

优雅的写法:

 1 import time
 2
 3 def show_time(f): #函数名作参数 ,装饰器
 4     def inner():
 5         start = time.time()
 6         f()
 7         end = time.time()
 8         print("spend %s" % (end - start))
 9     return inner
10
11 @show_time  #  foo = show_time(foo), 给foo函数添加一个计算所需时间的功能
12 def foo():
13     print("foo.....")
14     time.sleep(2)
15
16 #foo = show_time(foo)
17 foo()

11行,给foo函数添加一个计算所需时间的功能,@show_time,可理解为foo = show_time(foo)。

执行结果:

foo.....
spend 2.002133369445801

Process finished with exit code 0

被装饰函数参数(功能函数加参数):

 1 import time
 2
 3 def show_time(f): #函数名作参数 ,装饰器
 4     def inner(x, y):
 5         start = time.time()
 6         f(x, y)
 7         end = time.time()
 8         print("spend %s" % (end - start))
 9     return inner
10
11 @show_time  #  add = show_time(add), 给add函数添加一个计算所需时间的功能
12 def add(a, b):
13     print(a + b)
14     time.sleep(1)
15
16 #foo = show_time(foo)
17 add(1, 2)

执行结果:

3
spend 1.0010321140289307

Process finished with exit code 0

不定长参数:

 1 import time
 2
 3 def show_time(f): #函数名作参数 ,装饰器
 4     def inner(*x, **y):
 5         start = time.time()
 6         f(*x, **y)
 7         end = time.time()
 8         print("spend %s" % (end - start))
 9     return inner
10
11 @show_time
12 def add(*a, **b): # a为元组
13     sums = 0
14     for i in a:
15         sums += i
16     print(sums)
17     time.sleep(1)
18
19
20 add(1, 2, 5, 7, 9)#不定长参数

其中a为元组。

执行结果:

24
spend 1.0011086463928223

Process finished with exit code 0

装饰器参数:

 1 import time
 2
 3 def logger(flag=‘‘):#默认空
 4
 5     def show_time(f):  # 函数名作参数 ,装饰器
 6         def inner(*x, **y):
 7             start = time.time()
 8             f(*x, **y)
 9             end = time.time()
10             print("spend %s" % (end - start))
11             if flag == ‘true‘:
12                 print(‘日志记录‘)
13         return inner
14     return show_time
15
16 def show_time(f): #函数名作参数 ,装饰器
17     def inner(*x, **y):
18         start = time.time()
19         f(*x, **y)
20         end = time.time()
21         print("spend %s" % (end - start))
22     return inner
23
24 @logger(‘true‘) # 相当于@show_time,不过有了一个flag变量,相当于闭包
25 def add(*a, **b): # a为元组
26     sums = 0
27     for i in a:
28         sums += i
29     print(sums)
30     time.sleep(1)
31
33 add(1, 2, 5, 7, 9)#不定长参数
34
35 @logger()
36 def bar():
37     print("bar......")
38     time.sleep(3)
39
40 bar()

装饰器加参数flag,决定是否输出日志,此时show_time为闭包。

执行结果:

24
spend 1.001152515411377
日志记录
bar......
spend 3.00311541557312

原文地址:https://www.cnblogs.com/112358nizhipeng/p/9471695.html

时间: 2024-07-30 05:16:24

装饰器(函数)的相关文章

python全栈开发从入门到放弃之装饰器函数

1.函数名可以当作函数的参数 1 import time 2 def timmer(func): 3 #函数名可以当做函数的参数 4 def inner(): 5 start = time.time() 6 func() 7 end = time.time() 8 print(end - start) 9 return inner 10 11 def hahaha(): 12 time.sleep(0.1) 13 print('aaaa') 14 15 hahaha() 16 17 输出结果 1

函数(三) 装饰器函数

装饰器定义    装饰器其实也就是一个函数,一个用来包装函数的函数,返回一个修改之后的函数值,将新的值赋值原来的函数 2. 装饰器语法 1.函数名可以当作函数的参数 1 import time 2 def timmer(func): 3 #函数名可以当做函数的参数 4 def inner(): 5 start = time.time() 6 func() 7 end = time.time() 8 print(end - start) 9 return inner 10 11 def hahah

自己编写一个装饰器中的装饰器函数

看了"大道曙光"的<探究functools模块wraps装饰器的用途>的文章.基本上弄清了wraps的工作原理,为了检验一下自己理解的程度,于是动手写一个类似的 wraps函数,请大家指教. #!/usr/bin/env python # -*- coding: utf-8 -*- #filename : mywrapper.py #date: 2017-06-02 ''' wrapper function by my code.''' import functools i

property装饰器函数 @classmethod @staticmethod isinstance和issubclass

property函数   让方法伪装成属性   还有一系列的装饰器函数 1 class Goods: 2 __discount = 0.8 3 def __init__(self,price): 4 self.__price = price 5 self.name = 'apple' 6 7 @property #伪装成属性 8 def price(self): 9 return self.__price * Goods.__discount 10 11 @price.setter #修改折扣

property内置装饰器函数和@name.setter、@name.deleter

# property # 内置装饰器函数 只在面向对象中使用 # 装饰后效果:将类的方法伪装成属性 # 被property装饰后的方法,不能带除了self外的任何参数 from math import pi class Circle: def __init__(self, r): self.r = r def perimeter(self): return 2 * pi * self.r def area(self): return pi * self.r**2 * pi c1 = Circle

Python装饰器函数

装饰器函数 这里定义了一个func函数,打印'我是func函数' def func(): print('我是func函数'); time.sleep(1); 假设,想要在func()函数的基础之上新增的一个功能,计算func函数执行所用的时间 import time;#时间模块,处理时间操作 #开闭原则,对扩展开放,对修改封闭 def func(): print('我是func函数'); time.sleep(1);#休眠一秒 #tools方法就是func方法的装饰器 def tool(): d

python学习——装饰器函数

一.装饰器函数的作用是什么 答:装饰器函数是在不修改原函数及其调用方式的情况下对原函数功能进行扩展 对于搞python开发的人来说,函数占据了至关重要的地位.都说学好函数你就可以去找工作了,好了,假如你已经在某个公司上班了,想到马上就要过年了,那过年就意味着你可以向老板要年终奖金了,那凭什么老板要给你年终奖呢,你又能得到多少年终奖金呢.老板是这样说的,你给我至少写1000行代码,我来看一下你代码的执行时间,根据你的执行时间来评你的年终奖.好了,你知道既然要计算时间,学过函数的你就来实现一个计算函

装饰器函数(二)

装饰器进阶 1.带参数的装饰器就是在原有装饰器的基础上引入一个新的参数 多套一层函数,多传一个参数决定是否执行添加的功能,只是利用闭包多传了一个参数 和装饰器的原理一样,这次是把外界要传的参数通过在原有装饰器函数的基础上再套一层函数来实现的 现在装饰器函数最外层的作用只是在这个嵌套函数结构的空间里引入了一个新的局部变量,且变量的值由外部传入 此时多了一层函数嵌套,由于每一个函数名加上括号就是一层调用,因此要把@和@后面分开成两部分看,每一个函数名加上括号就是一层调用,因此要把@和@后面分开成两部

装饰器函数精讲

阅读目录 楔子 装饰器的形成过程 开放封闭原则 谈装饰器主要功能和装饰器固定结构 带参数的装饰器 多个装饰器装饰一个函数 举例函数 import time def timer(func): def inner(): start = time.time() func() print(time.time() - start) return inner @timer #==> func1 = timer(func1) def func1(): time.sleep(0.1) print('in fun

python之路--装饰器函数

(一)装饰器的形成过程 装饰器的本质是闭包函数的一种应用,装饰器是用来装饰函数的,在不修改原函数及其调用方式的情况下对原函数功能进行拓展. #简单的无参函数装饰器 import time def timmer(func): def inner(): start = time.time() func() end = time.time() print(end -start) return inner @timmer#语法糖 def hahaha(): time.sleep(2)#停止时间的一种用法