day11
1.今日概况
今日内容:
1.函数对象
2.函数嵌套
3.名称空间与作用域(******)
4.闭包函数=函数对象+函数嵌套定义+名称空间与作用域
2.函数的类型提示(type hinting)
def register(name: str, age: int) -> str: # ->str表示返回值类型是字符串
print(name)
print(age)
return 111
# register(1, 'aaa', [1, ])
# res = register('egon', 19, ('play', 'music'))
res = register(1111, 'egon')
print(register.__annotations__) # 查看自定义所有属性的提示信息
3.函数对象
# 精髓:可以把函数当成变量去用
# func=内存地址
def func():
print('from func')
# 1.可以赋值
f = func
print(f, func)
f()
# 2.可以当做函数的参数传入
def foo(x):
# print(x)
x()
# foo(func的内存地址)
foo(func)
# 3.可以当做函数当做另一个函数的返回值
def foo(x):
return x
res = foo(func)
print(res)
res()
# 4.当做容器类型的一个元素
l=[func,]
print(l)
l[0]()
dic={'k1':func}
print(dic)
dic['k1']()
4.小练习(函数对象应用案例)
def login():
print('登录功能')
def transfer():
print('转账功能')
def check_balance():
print('查询余额')
def with_draw():
print('提现')
func_dic = {
'1': login,
'2': transfer,
'3': check_balance,
'4': with_draw()
}
while True:
print("""
0.退出
1.登录
2.转账
3.查询余额
4.提现
""")
choice = input('请输入命令编号>>').strip()
if not choice.isdigit():
print('必须输入编号,傻叉')
continue
if choice in func_dic:
func_dic[choice]()
else:
print('这条命令不存在兄弟!')
5.函数的嵌套
1.函数的嵌套定义
# 1.函数的嵌套定义:在函数内定义其他函数
def f1():
def f2():
pass
# 圆形
def circle(radius, action=0):
# 求圆形的周长: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:
return perimiter(radius)
elif action == 1:
return area(radius)
res = circle(33, action=1) # 求周长action传0,求面积action传1
print(res)
2.函数的嵌套调用
# 函数嵌套
# 2.函数的嵌套调用:在调用的过程中又调用其他函数
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)
6.名称空间的概念
# 名称空间Namespaces:存放名字与其对应的内存地址的地方
# 名称空间分为三大类:
# 1、内置名称空间:存放的是python解释器自带的名字
# 生命周期:解释器启动则产生,解释器关闭则销毁
print(len)
print(input)
# 2、全局名称空间:存放的是顶级的名字
# 生命周期:py程序刚开始运行则立即产生,py程序结束
x = 10
if True:
y = 2
def foo():
z = 3
# 3、局部名称空间:存放的是函数内的名字
# 生命周期:函数调用则产生,函数调用结束则销毁
len = 111
def foo():
len = 222
# print(len)
foo()
print(len)
7.名称空间存活周期及作用域
作用域
内置名称空间
解释器级别的全局有效
全局名称空间
py文件级别的全局有效
局部名称空间
函数体代码内有效
1.什么是作用域?
作用域就是根据名称空间的范围和特点的不同进一步做了归类。内置名称空间和全局名称空间属于全局作用域,局部名称空间属于局部作用域。
2.全局作用域分为:全局名称空间、内置名称空间
特点:
全局存活
全局有效:被所有函数共享
3.局部作用域分为:局部名称空间的名字
特点:
临时存活
局部有效:函数内有效
8.名字的查找顺序简介
涉及到名字的查找 一定要先搞明白自己在哪个空间
1.当我们在局部名称空间中的时候
局部名称空间====>全局名称空间====>内置名称空间
2.当我们在全局名称空间中的时候
全局名称空间====>内置名称空间
ps:其实名字的查找顺序是可以打破的
9.名字查找注意事项及案例
1.相互独立的局部名称空间默认不能够互相访问
def func1():
name = 'jason'
print(age)
def func2():
age = 18
print(name)
2.局部名称空间嵌套
先从自己的局部名称空间查找 之后由内而外依次查找
"""
函数体代码中名字的查找顺序在函数定义阶段就已经固定死了
x = '干饭了'
def func1():
x = 1
def func2():
x = 2
def func3():
print(x)
x = 3
func3()
func2()
func1()
"""
10.LEGB
# LEGB原则
#
# python中作用域有四种:
# L(Local)==>作用域为函数内部
# E(Enclosing)==>作用域为外部嵌套函数
# G(Global)==>全局作用域
# B(Built-in)==>内置作用域 # 地球人
# 假设test为内置函数
test = 1 # Global # 中国人
def outer():
test = 2 # Enclosing # 安徽人
def inner():
test = 3 # Local # 安庆人
return test
return inner
print(outer()())
11.global与nonlocal关键字
关键字的使用
money = 666
def index():
money = 123
index()
print(money) # money为666
global使用
"""
局部名称空间直接修改全局名称空间的数据
"""
money = 666
# l1=[11,22,33]
def index():
global money
money = 123
index()
print(money)
nonlocal使用
'''
内层函数的局部名称空间修改外层函数局部名称空间中的数据
'''
def index():
name = 'jason'
def inner():
nonlocal name
name = 'kevin'
inner()
print(name)
index()