函数对象与闭包
一、函数对象
函数对象的本质:函数对象的本质是是一个变量,它可以被引用、可以作为一个容器对象的元素、可以作为函数的参数,甚至可以是一个函数的返回值。
(1)作为被引用的对象
def student(name, age, gender='male'): # student --> 0xffee0fc2
print('{0}的信息如下:\n姓名:{0}\n年龄:{1}\n性别:{2}'.format(name, age, gender))
s = student # s -->0xffee0fc2
s('王鹏',18)
s('姜春',18,gender='female')
(2)作为一个容器对象的元素
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from prettytable import PrettyTable
def login():
print('登录功能!')
def save():
print('存钱功能!')
def transfer():
print('转账功能!')
def withdraw():
print('取钱功能!')
def check_banlance():
print('查询余额功能!')
def register():
print('注册功能!')
func_choice= {
'0': ('退出', None),
'1': ('登录', login),
'2': ('存钱', save),
'3': ('转账', transfer),
'4': ('取钱', withdraw),
'5': ('查询余额', check_banlance),
'6': ('注册', register)
}
def atm_interface():
while True:
tb = PrettyTable(field_names=['功能编号', '功能名称'])
for k in func_choice:
tb.add_row([k, func_choice[k][0]])
print(tb)
user_choice = input('请输入功能编号:').strip()
if not user_choice.isdigit():
print('请输入一个正整数!')
continue
elif user_choice == '0':
break
elif user_choice in func_choice:
func_choice[k][1]()
else:
print('该功能尚未支持!')
_continue = input('是否继续(y,n):').strip().lower()
if _continue == 'y':
continue
else:break
atm_interface()
(3)作为一个参数传入另外一个函数
def outter(func):
def wrapper():
res = func()
print('hello,oldboy!')
return res
return wrapper
def test():
print('hello,shanghai!')
test = outter(test)
test()
sudo+ssh://root@192.168.80.130:22/usr/bin/python -u //practice/day16/practice_4.py hello,shanghai! hello,oldboy!
(4)函数的返回值可以是一个函数
def student():
print('hello, oldboy!')
def test(func):
print(func)
return func
print(student)
test(student)()
sudo+ssh://root@192.168.80.130:22/usr/bin/python -u //practice/day16/practice_4.py
<function student at 0x7ffb17de3ee0>
<function student at 0x7ffb17de3ee0>
hello, oldboy!
二、函数的嵌套
(1)函数的嵌套调用
在函数的调用过程中,又调用了其他的函数
def mymax(x,y):
return x if x>y else y
def vmax(a,b,c,d):
res1=mymax(a,b)
res2=mymax(c,d)
return mymax(res1,res2)
print('[4,6,1,3]中最大的数是:{}'.format(vmax(4,6,1,3)))
(2)函数的嵌套定义
在函数的定义过程中,包含另外一个函数的定义
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from math import pi
def circle(radius,action=0):
"""
action参数:(0,1)
0 -->求圆的周长 2*pi*radius
1 -->求圆的面积 pi*(radius**2)
"""
def perimeter():return 2*pi*radius
def area():return pi*(radius**2)
if action == 0:
res = perimeter()
else:res = area()
return res
print('半径为4的圆的周长为:{:.2f}'.format(circle(4)))
print('半径为6的圆的面积为:{:.2f}'.format(circle(6,action=1)))
三、闭包函数
# 闭包函数=名称空间与作用域+函数嵌套+函数对象
核心点:名字的查找关系是以函数定义阶段为准
(1)‘闭’与‘包’
# 闭”函数:该函数是内嵌函数 # 包"函数:该函数包含对外层函数作用域名字的引用(不是对全局作用域)
# 闭包函数:名称空间与作用域的应用+函数嵌套
def f1():
x = 2333
def f2():
print(x)
f2()
# 闭包函数:函数对象
def f1():
x = 2333
def f2():
print(x)
return f2
f = f1()
f()
(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号