【6】装饰器、闭包、偏函数、变量作用域问题
【一】、装饰器思想
装饰器是其实想增加一个函数的功能,但是又不想变动原来函数的代码,就用装饰器。
比如:我们用别人的一个函数,又不是很满意,所以用装饰器装饰一下即可。
def fun1(): print("嘉嘉 is a good man !") def outer(): print("****") fun1() outer()
【二】闭包
什么是闭包?
闭包:把一个函数当做一个参数传入另一个函数。本质上是一个返回函数的函数
案例1:简单的闭包实现装饰器代码
# 简单的装饰器 # 即以上起到了装饰器的作用,但是是写死了的,如何才能用一个调用来实现呢 # 闭包:把一个函数当做一个参数传入另一个函数。本质上是一个返回函数的函数 print('------------------------我是分割线-------------------------') def fun2(): print("嘉嘉 is a good man !") def outer2(fun): def inner(): print("****") fun() return inner # f代表是装饰后的返回的加强版的一个函数,并且是要装饰谁,把谁传进去。那么传入进去的东西被 # inner函数中的内容修饰了。 f=outer2(fun2) print(type(f)) f() ''' 输出: **** 嘉嘉 is a good man ! '''
其中:
f代表是装饰后的返回的加强版的一个函数,并且要装饰谁,把谁传进去。那么传入进去的东西被 # inner函数中的内容修饰了。
案例2:复杂一点的装饰器
1 # 案例2 :复杂一点的装饰器 2 def say(age): 3 print("she is %d years old " %(age) ) 4 5 # 写一个装饰器 6 def outer(func): 7 def inner(age): 8 if age<0: 9 age=0 10 say(age) 11 return inner 12 13 say2=outer(say) 14 # 此时调用的say2 其实就是outer函数返回的一个inner函数,say2他本身是函数 15 # 此时传入age=-5,执行say2函数,其实就是执行内存inner这个函数,
16 say2(-5) 17 say2(89) 18 ''' 19 输出是: 20 she is 0 years old 21 she is 89 years old 22 '''
总结:
4 # 此时调用的say2 其实就是outer函数返回的一个inner函数,say2他本身是函数 15
# 此时传入age=-5,执行say2函数,其实就是执行内存inner这个函数,
案例2-改进 :用标准的装饰器语法来写的话如下代码
# 案例2 改进 标准的装饰器 @outer #其实这个是等价 say2=outer(say) def say3(age): print("she is %d years old " %(age) ) # 写一个装饰器 def outer(func): def inner(age): if age<0: age=0 say(age) return inner # say2=outer(say) 上边给需要装饰的函数写了@ 这句话是可以直接省略的。 say3(-3) #注意:用@装饰完之后的函数名是不变的。 ''' 输出是: she is 0 years old '''
案例3-通用装饰器
此装饰器是通用版本,就不用担心传递的形参的个数问题啦
# 案例3 改进 通用装饰器 # 写一个装饰器 def outer2(func): def inner2(*args, **kwargs): ''' # 添加需要控制功能的语句块 if age<0: age=0 ''' print("我是装饰的代码块") return func(*args,**kwargs) return inner2 @outer2 def say4(age,name): print("she is %d years old ,Her name is %s "%(age,name) ) print("通用装饰器!") say4(-3,"佳佳") #注意:用@装饰完之后的函数名是不变的。 ''' 输出是:
我是装饰的代码块
she is -3 years old ,Her name is 佳佳
'''
案例1 简单的偏函数
# 偏函数:其实就是对形参的一个默认值的控制 def int_(str,base=2): return int(str,base) print(int_("1010")) # 输出:10
# 方法2 引入模块法
import functools
int3=functools.partial(int,base=2)
print(int3("1010"))
# 输出:10
作用域:
1、局部作用域
2、全局作用域
3、内建作用域
<未完待补充!>