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()
原文地址:https://www.cnblogs.com/wait59/p/13155106.html