函数名应用,闭包,装饰器初识
一、函数名的应用
函数名是一个变量,但他是一个特殊的变量,与括号配合可以执行函数的变量。
1、函数名的内存地址
def func(): print('哈哈') print(func) 结果: <function func at 0x00000000004E2E18>
2、函数名可以赋值给其他变量
def func(): print('哈哈') print(func) a = func #把函数当成一个变量,赋值给另一个变量 a() #调用函数 func()
3、函数名可以当做容器类元素
def func1(): print('哈哈') def func2(): print('呵呵') def func3(): print('嘻嘻') lst = [func1,func2,func3] for i in lst: i()
4、函数名可以当做函数的参数
def func(): print('吃了吗?') def func2(fn): print('我是func2') fn() #执行传递过来的fn print('我是func2') func2(func) #把函数func当成参数传递给func2的参数fn
5、函数名可以作为函数的返回值
def func1(): print('这里是函数1') def func2(): print('这里是函数2') print('这里是函数1') return func2 fn = func1() #执行函数1,函数1返回的是函数2,这时fn指向的就是上面函数2 fn() #执行上面返回的函数
执行结果:
这里是函数1
这里是函数1
这里是函数2
二、闭包
闭包就是内层函数对外层函数(非全局)变量的引用。
def func1(): name = 'alex' def func2(): print(name) #闭包 func2() func1() # 结果: alex
我们可以使用_closure_来检测函数是否是闭包,使用函数名._closure_返回cell就是闭包,返回None就不是闭包。
def func1(): name = 'alex' def func2(): print(name) func2() print(func2.__closure__) #(<cell at 0x00000000027A4618: str object at 0x0000000002927730>,) func1()
如何在函数外边调用内部函数呢? return
def func1(): name = 'alex' # 内部函数 def func2(): print(name) return func2 fn = func1() #访问外部函数,获取到内部函数的函数地址 fn() #访问内部函数
如果多层嵌套呢,只需要一层一层的往外层返回就行了
def func1(): def func2(): def func3(): print('哈哈') return func3 return func2 func1()()()
python规定,如果你在内存函数中访问了外层函数的变量,那么这个变量将不会消亡,将会常驻内存。也就是说,使用闭包,可以保证外层函数中的变量在内存中常驻。
闭包的作用就是让一个变量能够常驻内存,供后面的程序使用。
三、装饰器初识
软件设计原则一、开闭原则。 开放:对功能扩展开放 封闭:对修改代码封闭
def fruit(): print('结果') def water(fn): def inner(): print('浇水') fn() print('开花') return inner fruit = water(fruit) fruit()
语法糖:@装饰器
def water(fn): def inner(): print('浇水') fn() print('开花') return inner @water #相当于fruit = water(fruit) def fruit(): print('结果') fruit()
带返回值的装饰器
def wen_jin(fn): def inner(*args,**kwargs): print('质量怎么样') ret = fn(*args,**kwargs) print('骗我') return ret return inner @wen_jin def yue(name): print('约一约',name) return '小萝莉' ret = yue('小姐姐') print(ret)
装饰器模型代码
#装饰器:对传递进来的函数进行包装,可以在目标函数之前和之后添加任意的功能 def wrapper(func): def inner(*args,**kwargs): '执行目标函数之前要执行的内容' ret = func(*args,*kwargs) '执行目标函数之后要执行的内容' return ret return inner @wrapper #相当于target_func = wrapper(target_func) 语法糖 def target_func(): print('我是目标函数') #调用目标函数 target_func()