函数对象与闭包
1. 函数对象
精髓:可以把函数当成变量去使用
1.1 函数可以被引用
def func(): pass # func=内存地址 f = func print(f,func) f()
1.2 函数可以作为容器类型的元素
def func(): print('111') l = [func, ] l[0]() dic = {'k1': func} print(dic) # 函数对象引用示范 def login(): print('登录功能') def transfer(): print('转账功能') def check_banlance(): print('查询余额') def withdraw(): print('提现') def register(): print('注册') func_dic = { '0': ['退出', None], '1': ['登录', login], '2': ['转账', transfer], '3': ['查询余额', check_banlance], '4': ['提现', withdraw], '5': ['注册', register] } while True: for k in func_dic: print(k, func_dic.get(k)[0]) choice = input('请输入命令编号:').strip() if not choice.isdigit(): print('请输入编号') continue if choice == '0': break # choice = '1' if choice in func_dic: func_dic[choice][1]() else: print('指令不存在')
1.3 函数可以作为参数传入另一个函数
def func(): pass def foo(x): print(x) print(func) foo(func)
1.4 函数的返回值可以是一个函数
def func(): print('111') def foo(x): return x
1.5 函数嵌套
- 1.5.1 函数嵌套的调用
def max2(x, y): if x > y: return x else: return y def max4(a, b, c, d): # 第一步:比较a,b得到res1 res1 = max2(a, b) # 第二步:比较res1,c得到res2 res2 = max2(res1, c) # 第三步:比较res2,d得到res3 res3 = max2(res2, d) return res3 res = max4(1, 2, 3, 4) print(res)
- 1.5.2 函数的嵌套定义:在函数内定义函数
def circle(radius, action=0): """ action参数 0:求周长 1:求面积 """ # 求圆形的周长=2 * pi * radius from math import pi def perimiter(radius): return 2 * pi * radius # 求圆形的面积=pi*(radius**2) def area(radius): return pi * (radius ** 2) if action == 0: res = perimiter(radius) elif action == 1: res = area(radius) return res res = circle(3, action=1) print(res)
2. 闭包函数
闭包函数=名称空间与作用域+函数嵌套+函数对象
2.1 闭与包
基于函数对象的概念,可以将函数返回到任意位置去调用,但作用域的关系是在定义完函数时就已经被确定了的,与函数的调用位置无关。
x = 1 def f1(): def f2(): print(x) return f2 def f3(): x = 3 f2 = f1() # 调用f1()返回函数f2 f2() # 需要按照函数定义时的作用关系去执行,与调用位置无关 f3()
也就是说函数被当做数据处理时,始终以自带的作用域为准。若内嵌函数包含对外部函数作用域(而非全局作用域)中变量的引用,那么该‘内嵌函数’就是闭包函数,简称闭包
x = 1 def outer(): x = 2 def inner(): print(x) return inner func = outer() func()
可以通过函数的closure属性,查看到闭包函数所包裹的外部变量
>>> func.__closure__ (<cell at 0x10212af78: int object at 0x10028cca0>,) >>> func.__closure__[0].cell_contents 2
- “闭”代表函数是内部的
-
“包”代表函数外‘包裹’着对外层作用域的引用
无论在何处调用闭包函数,使用的仍然是包裹在其外层的变量
2.2 闭包的用途
向函数传参的另一种方式
# 两种为函数体传参的方式 # 方式一:直接把函数体需要的参数定义成形参 def f2(x): print(x) f2(1) f2(2) f2(3) # 方式二: def f1(x): # x=3 x = 3 def f2(): print(x) return f2 x = f1(3) print(x) x() # 应用场景 import requests # 传参方案一: def get(url): response = requests.get(url) print(len(response.text)) get('https://www.baidu.com') get('https://www.cnblogs.com/linhaifeng') get('https://zhuanlan.zhihu.com/p/109056932') # 传参方式二: def outter(url): # url='https://www.baidu.com' def get(): response = requests.get(url) print(len(response.text)) return get baidu = outter('https://www.baidu.com') baidu() cnblogs = outter('https://www.cnblogs.com/linhaifeng') cnblogs() zhihu = outter('https://zhuanlan.zhihu.com/p/109056932') zhihu()

浙公网安备 33010602011771号