day 16 函数对象,闭包
1 函数对象
精髓:可以把函数当成变量去用,函数对象指的是函数可以被当做’数据’来处理,具体可以分为四个方面的使用
func=内存地址
def func():
print('from func')
1.1 可以赋值
f=func
print(f, func)
f()
1.2 可以当做函数当做参数传给另外一个函数
def foo(x):
print(x)
x = func #内存地址
foo(func) # foo(func 的内存地址)
-----------------------------------------
>>> def foo(x,y,func):
... return func(x,y)
...
>>> foo(1,2,add)
3
1.3 可以当做函数当做另外一个函数的返回值
def foo(x): # x=func 的内存地址
return x # return func 的内存地址
res=foo(func) # foo(func 的内存地址)
print(res) # res=func 的内存地址
res()
-----------------------------------
def bar():
return add
func=bar()
func(1,2)
3
1.4 可以当做容器类型的一个元素
l=[func, ]
print(l)
l [0] ()
----------------------
dic={'k1':func}
print(dic)
dic ['k1'] ()
1.5 函数对象应用示范:
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[k][0])
choice = input('请输入命令编号:').strip()
if not choice.isdigit():
print('必须输入编号,傻叉')
continue
if choice == '0':
break
if choice in func_dic:
func_dic[choice][1]()
else:
print('输入的指令不存在')
2 函数嵌套
2.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)
2.2 函数的嵌套定义:在函数内定义其他函数
def f1():
def f2():
pass
--------------------------------------
**求圆形的求周长:2 * pi * radius**,**求圆形的求面积:pi*(radius * * 2)**
def circle(radius,action=0):
from math import pi
if action == 0:
def perimiter(radius):
return 2 * pi * radius
elif action == 1:
def area(radius):
return pi*(radius**2)
circle(33,action=0)
3 闭包函数
3.1 大前提:
闭包函数 = 名称空间与作用域 + 函数嵌套 + 函数对象
核心点:名字的查找关系是以函数定义阶段为准
3.2 什么是闭包函数
"闭" 函数指的该函数是内嵌函数
"包" 函数指的该函数包含对外层函数作用域名字的引用(不是对全局作用域)
闭包函数:名称空间与作用域的应用 + 函数嵌套
基于函数对象的概念,可以将函数返回到任意位置去调用,但作用域的关系是在定义完函数时就已经被确定了的,与函数的调用位置无关。
- 引入
x=1
def f1():
def f2():
print(x)
return f2
def f3():
x=3
f2=f1() #调用f1()返回函数f2
f2() #需要按照函数定义时的作用关系去执行,与调用位置无关
f3() #结果为1
- 闭包函数:函数对象
def f1():
x = 33333333333333333333
def f2():
print('函数 f2:',x)
return f2
f=f1()
def foo():
x=5555
f()
foo()
-----------------------------------
x=1
def outer():
x=2
def inner():
print(x)
return inner
func=outer()
func() # 结果为2
- 可以通过函数的closure属性,查看到闭包函数所包裹的外部变量
>>> func.__closure__
(<cell at 0x10212af78: int object at 0x10028cca0>,)
>>> func.__closure__[0].cell_contents
2
“闭”代表函数是内部的,“包”代表函数外’包裹’着对外层作用域的引用。因而无论在何处调用闭包函数,使用的仍然是包裹在其外层的变量。
3.3 为何要有闭包函数(闭包函数的应用)
两种为函数体传参的方式
- 方式一:直接把函数体需要的参数定义成形参
def f2(x):
print(x)
f2(1)
f2(2)
f2(3)
- 方式二:闭包
def f1( ):
x=3
def f2():
print(x)
return f2
x=f1(3)
print(x)
x()

浙公网安备 33010602011771号