python函数之进阶 函数嵌套,命名空间,闭包
python函数之进阶
目录
1:函数嵌套
一:什么是函数嵌套
在一个函数内又定义了另外一个函数
二:函数定义
def foo():
def bar()
print('from bar')
bar()
foo()
# 这个是通过foo函数调用里面的bar函数
def foo():
def f2():
print('from f2')
return f2
print(foo()) # 返回的是一个f2函数内存地址
# //////////////////////
foo()()
res = foo()
res()
#这两种都是调用f2函数
示例
def circle(radius,mode):
import math
def perimiter(radius):
return 2 * math.pi * radius
def area(radius):
return math.pi * (radius ** 2)
if mode == 1:
return perimiter(radius)
elif mode == 2:
return area(radius)
print(circle(1,1))
print(circle(1,2))
三:嵌套函数调用
在调用一个函数的过程中又调用了其他函数
def max2(x, y):
if x > y:
return x
else:
return y
def max3(x, y, z):
res = max2(x, y)
res1 = max2(res,z)
return res1
print(max3(1,4,19))
2:函数名称空间与查找顺序
一:名称空间
一:内置名称空间
内置名称空间:存放的是python解释器自带的名字,如len,print,input....
生命周期:解释器启动则创建,解释器关闭就销毁
二:全局名称空间
全局名称空间:内置以及函数内的名字之外的名字都存放于全局名称空间中
生命周期:运行顶级代码/主流水线则创建,顶级代码/主流水线结束则销毁,
x = 10
y = 12
def bar():
z = 111
def f1():
print('from f1')
if True:
ccc = 33
x,y,bar ccc 都是全局变量
三:局部名称空间
局部名称空间:函数内的名字
生命周期:函数调用时则创建,函数调用完毕则立即销毁
def foo(x,y):
c = 3
def bar(x,y):
xx = 88
oo = 99
bar()
foo()
c,bar,xx,oo都是局部变量
x = 111
def f3():
print(x)
# x = 333
x = 222
f3()
如果x = 333没有注释会报错,当解释器在运行代码时,函数体代码并不会执行,只会看这个函数定义是否正常,执行的时候就会解释并执行代码。内部想打印x,但是x是在print下方才被定义,还有一个原因解释器是由上到下解释并执行代码的。所以会报错
注释后:结果是222,原因是在解释器解释执行代码的时候x=111,被创建了,f3只是检查了定义是否正常,x=222覆盖了x=111,所以调用f3的时候,函数会在内找变量,如果没有在全局找,找到了x=222
二:名称空间名字的查找顺序
一:全局 查找
name = 444
def f1():
name =4444
f1()
print(f1) # 444
def foo():
print(name)
name = 33333
foo() # 33333
二:局部查找
def bar()
name = 4444
print(name)
name = 44
bar() # 4444
def foo():
age = 18
print(age)
def bar():
age = 28
print(age)
age = 88
foo() # 18
bar() # 28
def foo():
name = 88
def inner():
name = 44
print(name)
inner()
foo() #如果inner内部的name注释了结果就是88,没有就是44
x = 8
def f1():
print(x)
def f2():
x=22
f1()
f2() # 结果是8
warning:名称空间的"嵌套关系"是函数定义阶段、也就是检测语法的时候就确定的,与调用为无关
3:函数作用域
一:全局作用域
内置名称空间、全局名称空间.全局存活、全局有效
二:局部作用域
:局部名称空间,临时存活,局部有效
4:函数的参数传递都是值拷贝
一:对全局定义的不可变类型,可以在函数内不直接修改
x = 10
def func(a):
a = 123
func(x)
二:对全局定义的可变类型,可以在函数内直接修改
x = []
def func(a):
a.append(22)
func(x)
三: 在函数内修改全局的不可变类型
x = 10
l = []
def func():
global x
x=6666
l.append(11111)
func()
print(x)
print(l)
四:nonlocal(了解)
x = 10
def foo():
x=11
def f2():
nonlocal x
x='老铁66666666'
f2()
print('foo内的x---->',x)
foo()
print(x)
5:闭包函数
一:什么是闭包函数?
闭包函数-->函数对象+函数嵌套定义+名称空间与作用域
闭包函数
闭:指的是定义函数内的函数
包:指的内函数引用了外函数的变量
def wrapper():
x = 1111
def inner():
print(x)
return inner # 加括号返回的是inner函数的返回值,不加是函数的内存地址
f = wrapper()
print(f)
def f3():
x = 333333
f()
f3()
二:为函数体代码传参的方式
一:直接通过参数的方式传入
def func(x):
print(x)
func(1)
func(2)
func(3)
二:通过函数传递参数
def wrapper(x):
# x = 3
def inner():
print(x)
return inner
f1 = wrapper(1)
f2 = wrapper(2)
f3 = wrapper(3)
f4 = wrapper(4)
f1()
f2()
f3()
f4()