Python函数对象与闭包
#一:函数对象:
函数对象指的是函数可以被当做‘数据’来处理,精髓在于可以把函数当成变量去用
# 1、可以赋值
# func=内存地址
def func():
print("新年快乐!!!")
f=func #你加括号拿的是返回值,不是对应的函数地址
print(f,func)
f()
#输出结果:
<function func at 0x000002A9F6559790> <function func at 0x000002A9F6559790>
新年快乐!!!
#2.函数可以作为参数传递给另外一个函数
def foo(x):
print(x)
x()
foo(func)
#输出结果为:
<function func at 0x000001C3162F9790>
新年快乐!!!
#3.函数可以当作另外一个函数的返回值
def back_you(x):
return x
f1=back_you(func)
print(f1)
f1()
输出结果为:
<function func at 0x000001855F8A9790>
新年快乐!!!
#4.函数可以当作一个容器类型的元素
l=[func,]
print(l[0])
l[0]()
dict={'k1':func}
print(dict['k1'])
dict['k1']()
输出结果为:
<function func at 0x00000133B7F99790>
新年快乐!!!
<function func at 0x000002719A589790>
新年快乐!!!
#5.函数对象示例,简单的银行小游戏
def register():
print('您正在使用注册功能!!!')
def login():
print('您正在登录!!!')
def login_out():
print("您已退出登录!!")
def deposit():
print("正在进入存钱服务!!")
def withdraw():
print('正在进入取钱服务!!!')
number={'0':["注册",register],
'1':["登录",login],
'2':["退出",login_out],
'3':["存钱",deposit],
'4':["取钱",withdraw]
}
while True:
print("欢迎进入银行管理系统")
for x in number:
print(x+number[x][0])
input_number=input("请输入您想要的服务序号").strip()
if(input_number.isdigit()!=True):
print("傻叉请输入数字")
continue
elif(input_number=="2"):
print("您已退出")
break
else:
number[x][1]()
break
#6.函数的嵌套
#函数的嵌套调用是指在调用一个函数的过程中又调用其他函数
def max(num1,num2):
if(num1>=num2):
return num1
else:
return num2
def max_four(num1,num2,num3,num4):
max1=max(num1,num2)
max2=max(num3,num4)
return max(max1,max2)
print(max_four(1,2,5,8))
#函数的嵌套定义是指在一个函数的定义中又定义其他函数
def f1():
def f2():
pass
#函数的嵌套定义示例(求园的周长与面积)
def circle(radius,action=0):
from math import pi
def area():
return pi*radius**2
def perimeter():
return 2*pi*radius
if action==0:
return area()
else:
return perimeter()
print(circle(5)) #输出面积
print(circle(5,action=2)) #输出周长
#输出结果:
78.53981633974483
31.41592653589793
#二:闭包函数
1 闭包函数=名称空间与作用域+函数嵌套+函数对象
# 核心点:名字的查找关系是以函数定义阶段为准,基于函数对象的概念,可以将函数返回到任意位置去调用,
# 但作用域的关系是在定义完函数时就已经被确定,与函数的调用位置无关
2 什么是闭包函数
# "闭"函数指的该函数是内嵌函数
# "包"函数指的该函数包含对外层函数作用域名字的引用(不是对全局作用域) 只要不是我的,外面多少层无所谓
# 也就是说函数被当做数据处理时,始终以自带的作用域为准,若内嵌函数包含对外部作用域(而非全局作用域)中变量的引用,那么该内嵌函数就是闭包函数,简称闭包(Closure)
#闭包的示例
def f1():
x = 33333333333333333333
def f2():
print(x)
f2()
x=11111
def bar():
x=444444
f1()
def foo():
x=2222
bar()
foo()
#运行的结果是:33333333333333333333
#始终记住!!!函数被当做数据处理时,始终以自带的作用域为准
3:闭包函数,函数对象
def f1():
x=201314
def f2():
print(x)
return f2 #将f2丢到全局变量
f=f1() #让f2能够到全局运行
print(f)
#这里输出结果:<function f1.<locals>.f2 at 0x000002050B309820>
x=520
f()
def foo():
x=5201314
f() #如何变化都改变不了到麻袋里面(定义阶段)找吃的本质
foo()
#这里两个输出都是201314
#4:为何要有闭包函数,闭包函数的应用
# 两种为函数体传参的方式
# 方式一:直接把函数体需要的参数定义成形参
def f2(x):
print(x)
f2(1)
f2(2)
f2(3)
# 方式二:利用名称空间的概念给他
def f1(x):
print(x)
def f2():
print(x)
return f2
f=f1(3)
print(f)
f()
输出结果为:
3
<function f1.<locals>.f2 at 0x0000016E58949820>
3
#5:闭包函数关于两种传参方式的示例
#1直接传参
import requests
def get_web_messagelen(url):
response=requests.get(url)
print(len(response.text))
get_web_messagelen('https://www.baidu.com/?tn=80035161_1_dg')
#2间接传参。利用名称作用域的概念
def outter(url):
def get_webtext_len():
response=requests.get(url)
print(len(response.text))
return get_webtext_len
baidu=outter('https://www.baidu.com/?tn=80035161_1_dg')
baidu()
#输出结果都为2443
#选择哪一种看你的需求啦,不要以为没有第二种传参方式的需求
浙公网安备 33010602011771号