函数(二)
——------------------------------------------------------内容概要-----------------------------------------------
名称空间
- 名称空间的本质
- 名称空间的分类
- 存活周期
作用域
名字的查找顺序
global与nonlocal关键字
- global关键字
- nonlocal关键字
函数的多种用法
函数的嵌套
——---------------------------------------------------------------------------------------------------------------
名称空间
名称空间的本质 '名称空间' 其实就是用于存放变量名与变量值绑定关系的一个地方
# 可以比作成生活中的民政局 ??
名称空间的分类
'名称空间的分类'
# 1.内置名称空间
python解释器提前给我们定义好的
len() print() open() # 内置方法 内置函数都存在与内置名称空间
# 2.全局名称空间
'''在py文件中编写的代码运行产生的名字都会存到全局名称空间
顶格写的代码都会存在全局名称空间'''
num = 100 # 变量名num存入全局名称空间里
def name() # 函数名name会存入全局名称空间里
if Ture:
a = 1 # 变量名a会存入全局名称空间
for b in range(7): # 变量名b会存入全局名称空间里
pass
while True:
c = 22 # 变量名c会存入全局名称空间里
# 3.局部名称空间
函数体代码运行产生的都是局部名称空间
def index():
name = 'jason' # name存入局部名称空间
存活周期
'存活周期'
# 1.内置名称空间
python解释器开始运行时 产生
python解释器关闭时 销毁
# 2.全局名称空间
py文件开始运行时 产生
py文件结束运行时 销毁
# 3.局部名称空间
函数体代码被调用(运行)时 产生
函数体代码运行结束时 销毁
"作用域就是名称空间能够作用的范围"
# 内置名称空间
程序任意阶段任意位置均可使用(全局有效)
# 全局名称空间
程序任意阶段任意位置均可使用(全局有效)
# 局部名称空间
一般情况下只在各自局部名称空间中有效(局部有效)
'''也可以通过关键字或其他方法来的打破规则'''
名字的查找
'''
名称空间是用来存放名字与值绑定关系的地方
如果我们想要查找某一个名字时 该如何去查找 按照什么规则来找
在哪个名称空间找 查找的顺序是怎样的
'''
"在查找时一定要清楚查找时所在的名称空间位置"
# 在局部名称空间时
先从局部名称空间>>>全局名称空间>>>内置名称空间 # 如都找不到就会报错
# 在局部名称空间时
全局名称空间>>>内置名称空间 # 如都找不到就会报错
len = '我是全局名称空间中的len'
# 注释后 位置在全局名称空间的len 先从全局名称空间>>>内置名称空间
def index():
len = '我是局部名称空间中的len'
print(len) # 位置在局部名称空间 先从局部>>全局>>>内置名称空间
index() # 调用函数 函数体就会执行 就会产生局部名称空间
print(len) # 位置在全局名称空间 先从全局名称空间>>>内置名称空间
# 全局 我是全局名称空间中的len 在内置名称空间:
'''如局部名称空间之间不存在嵌套而时同一级时
那么互不干涉!!!'''
def num1():
n = 20
def num2():
age = 18
print(n) # 报错
num1()
num2()
global关键字
'''
global关键字:打破局部名称空间不可修改全局名称空间中
相同的不可变类型的规则'''
eg:
n = 154
def num():
global n # 申明 修改全局的n
n = 250
num() # 函数调用
print(n) # 全局的154修改为250
'''若想要在局部修改全局的可变类型
不需要加关键字global申明,直接修改即可'''
nonlocal关键字
'''
作用于函数嵌套时里层局部命名空间修改外层局部命名空间的不可变类型的值
'''
eg:
n = 154
def num():
n = 250
def num1():
nonlocal n
n = 520
num1() # 函数调用
print(n) # 全局的250修改为520
num() # 函数调用
''' 若想要在里层局部修改外层局部的可变类型
不需要加关键字nonlocal申明,直接修改即可'''
函数的多种用法
# 用法方法1
"函数名可以当做变量名赋值"
eg:
def fire():
print('my god!!!')
wft = fire # 让变量名wft也指向函数体代码
wft() # 类似于 fire()
# 用法方法2
"函数名还可以当成函数的实参"
eg:
def fire():
print('my god!!!')
def car(a):
print('my car are break!!')
a()
car(fire) # 函数名fire充当实参
# 用法方法3
"函数名还可以当做函数的返回值"
eg:
def func():
print('from func')
return index # 将函数名当做返回值
def index():
print('from index')
res = func() # res接收函数名
print(res) # 指向的是index函数的内存地址
res() # index()
# 用法方法4
"函数名可以作为容器类型的元素"
'''容器类型:内部可以存档多个元素的数据类型>>>:列表、元组、字典'''
eg:
def num():
print('from num')
l1 = [1, 2, 3, 4, num]
print(l1)
l1[-1]() # 索引取值-1() 相当于 num()
函数的嵌套
# 函数的嵌套调用
def index():
func() # 调用func函数
print('from index')
def func():
index() # 调用index函数
print('from func')
func()
'''两个函数间一直在调来调去 类似与死循环 最终会报错'''
# 比较数字的大小
def my_max(a,b):
'''返回两个数中的较大值'''
if a > b:
return a
return b
# print(my_max(100,999))
def many_max(a,b,c,d):
'''返回四个数中的最大值'''
res = my_max(a,b) # 两两先比
res1 = my_max(res,c) # ...
res2 = my_max(res1,d) # ...
...