文章目录
昨日内容回顾
1、名称空间namespaces
名字-》栈区
名称空间是对栈的一种划分,真正存在的是栈区,名称空间只是一种虚拟的划分
内置名称空间(x)
全局名称空间(x)
局部名称空间(x)
重点1:
名词查找:当前所在的位置向外查找
局部名称空间->全局名称空间->内置名称空间
重点2:
名称空间只有优先级之分,本身并无嵌套关系,画图只是为了理解
重点3:
名称空间的嵌套关系决定了名字的查找顺序
而名称空间的嵌套关系是以函数定义阶段为准的,
即函数的嵌套关系与名字的查找顺序是在定义阶段就已经确定好的
x=111
def f1():
print(x)
x=222
f1()
全局作用域:内置名称空间+全局名称空间的名字
全局存活,全局有效
局部作用域:
临时存活,局部有效
nonlocal
今日内容概要
1、函数对象(可以把函数当成变量去用)
2、函数嵌套
3、闭包函数=名称空间与作用域+函数嵌套+函数对象
核心点:名字的查找关系是以函数定义阶段为准
今日内容详细
精髓:可以把函数当成变量去用
func = 内存地址
def func():
print('from func')
可以赋值
f = func
print(f, func)
f()
可以当做函数当做参数传给另外一个函数
def foo(x): # x = func的内存地址
# print(x)
x()
foo(func) # foo(func的内存地址)
可以当做函数当做另外一个函数的返回值
def foo(x): # x=func的内存地址
return x # return func的内存地址
res = foo(func) # foo(func的内存地址)
print(res) # res=func的内存地址
res()
可以当做容器类型的一个元素
l = [func, ]
# print(l)
l[0]()
dic = {'k1': func}
print(dic)
dic['k1']()
函数对象应用示范
原始版
def login():
print('登录功能')
def transfer():
print('转账功能')
def check_banlance():
print('查询余额')
def withdraw():
print('提现')
def register():
print('注册')
func_dic = {
'1': login,
'2': transfer,
'3': check_banlance,
'4': withdraw,
'5': register
}
# func_dic['1']()
while True:
print("""
0 退出
1 登录
2 转账
3 查询余额
4 提现
5 注册
""")
choice = input('请输入命令编号:').strip()
if not choice.isdigit():
print('必须输入编号,傻叉')
continue
if choice == '0':
break
if choice in func_dic:
func_dic[choice]()
else:
print('输入的指令不存在')
# if choice == '1':
# login()
# elif choice == '2':
# transfer()
# elif choice == '3':
# check_banlance()
# elif choice == '4':
# withdraw()
# else:
# print('输入的指令不存在')
修正版
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]
}
# func_dic['1']()
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
# choice='1'
if choice in func_dic:
func_dic[choice][1]()
else:
print('输入的指令不存在')
函数嵌套
函数的嵌套调用
在调用一个函数的过程中又调用其他函数
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)
函数的嵌套定义: 在函数内定义其他函数
def f1():
def f2():
pass
# 示范
# 求圆形的求周长:2*pi*radius
def circle(radius, action=0):
from math import pi
def perimiter(radius):
return 2*pi*radius
# 求圆形的求面积:pi*(radius**2)
def area(radius):
return pi*(radius**2)
if action == 0:
return 2*pi*radius
elif action == 1:
return area(radius)
circle(33, action=0)
闭包函数
一:大前提:
闭包函数 = 名称空间与作用域+函数嵌套+函数对象
核心点:名字的查找关系是以函数定义阶段为准
二:什么是闭包函数
"闭"函数指的该函数是内嵌函数
"包"函数指的该函数包含对外层函数作用域名字的引用(不是对全局作用域)
闭包函数:名称空间与作用域的应用+函数嵌套
def f1():
x = 33333333333333333333
def f2():
print(x)
f2()
x = 11111
def bar():
x = 444444
f1()
def foo():
x = 2222
bar()
foo()
闭包函数:函数对象
def f1():
x = 33333333333333333333
def f2():
print('函数f2:', x)
return f2
f = f1()
# print(f)
# x=4444
# f()
def foo():
x = 5555
f()
foo()
闭包函数的应用
两种为函数体传参的方式
方式一:直接把函数体需要的参数定义成形参
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()
传参的方案一:
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()
作业
今日作业:
1、函数对象优化多分支if的代码练熟
2、编写计数器功能,要求调用一次在原有的基础上加一
温馨提示:
I:需要用到的知识点:闭包函数+nonlocal
II:核心功能如下:
def counter():
x+=1
return x
要求最终效果类似
print(couter()) # 1
print(couter()) # 2
print(couter()) # 3
print(couter()) # 4
print(couter()) # 5
# ====================周末作业====================
# 编写ATM程序实现下述功能,数据来源于文件db.txt
# 0、注册功能:用户输入账号名、密码、金额,按照固定的格式存入文件db.txt
# 1、登录功能:用户名不存在,要求必须先注册,用户名存在&输错三次锁定,登录成功后记录下登录状态(提示:可以使用全局变量来记录)
下述操作,要求登录后才能操作
# 1、充值功能:用户输入充值钱数,db.txt中该账号钱数完成修改
# 2、转账功能:用户A向用户B转账1000元,db.txt中完成用户A账号减钱,用户B账号加钱
# 3、提现功能:用户输入提现金额,db.txt中该账号钱数减少
# 4、查询余额功能:输入账号查询余额