013.Python之函数嵌套名称空间与作用域闭包函数
Posted huluhuluwa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了013.Python之函数嵌套名称空间与作用域闭包函数相关的知识,希望对你有一定的参考价值。
目录
一、函数嵌套
(一)什么是函数嵌套
在一个函数内又定义了另外一个函数。
def f1():
def f2():
print("from f2")
f2()
x = 1111
return x
f1() # from f2
print(f1()) # from f2 函数运行时输出的值
# 1111 函数的返回值
===============================================================================
def f1():
def f2():
print(‘from f2‘)
return f2
res=f1()
print(res) # <function f1.<locals>.f2 at 0x000002EB71159040> f2的内存地址
res() # from f2
===============================================================================
import math
def circle(radius,mode):
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(18,1)) # 113.09733552923255
print(circle(18,2)) # 1017.8760197630929
(二)函数嵌套的调用
在调用一个函数的过程中又调用了其他函数。
def max2(x, y):
if x > y:
return x
else:
return y
def max4(a, b, c, d):
res1 = max2(a, b)
res2 = max2(res1, c)
res3 = max2(res2, d)
return res3
print(max4(1,2,3,4)) # 4
二、名称空间与作用域
(一)名称空间
名称空间就是存放名字的地方
1.内置名称空间
存放的是python解释器自带的名字,如len、print、input等。
生命周期:解释器启动则创建,解释器关闭就销毁。
2.全局名称空间
内置以及函数内的名字之外的名字都存放于全局名称空间中。
生命周期:运行顶级代码/主流水线则创建,顶级代码/主流水线结束则销毁。
# foo = 内存地址
def foo(): # foo本身也是全局的
z = 111
# f1=内存地址
def f1():
pass
if True: # if语句是全局的
aaa = 33
3.局部名称空间
函数内的名字。
生命周期:函数调用时则创建,函数调用完毕则立即销毁。
def f1(x, y):
z = 3
def f2():
m=444
n=5555
f2()
f1(1, 2)
print(f1(1, 2)) # None 没有返回值,默认None
(二)名称空间名字的查找顺序
查找顺序:基于当前所在的位置向上查找。
# 局部-》外层套的局部-》外层套的局部-》....-》全局-》内置
# 示范1:站在全局进行查找
input = 333
def f1():
input = 444
f1()
print(input) # 333
# 示范2:站在局部进行查找
def f1():
# input = 4444
print(input)
input = 333
f1() # 333
def f1():
input = 4444
print(input)
input = 333
f1() # 4444
# 示范3
# 3.1
def f1():
input = 444
print(input)
def f2():
input = 555
print(input)
input = 333
f1() # 444
f2() # 555
# 3.2
def f1():
input = 444
print(input)
def f2():
# input = 555
print(input)
input = 333
f1() # 444
f2() # 333
# 3.2
def f1():
input = 444
print(input)
def f2():
# input = 555
print(input)
# input = 333
f1() # 444
f2()
# 示范4:
# 示范4.1:
def f1():
input = 444
def inner():
input = 555
print(input)
inner()
input = 333
f1() # 555
# 示范4.2:
def f1():
input = 444
def inner():
# input = 555
print(input)
inner()
input = 333
f1() # 444
# 示范4.3:
def f1():
# input = 444
def inner():
# input = 555
print(input)
inner()
input = 333
f1() # 333
# 示范4.4:
def f1():
# input = 444
def inner():
# input = 555
print(input)
inner()
# input = 333
f1() # <built-in function input>
# 强调:名称空间的"嵌套关系"是函数定义阶段、也就是检测语法的时候就确定的,与调用为无关。
x = 111
def f1():
print(x)
def f2():
x = 222
f1()
f2() # 111
# 示范5:
def f3():
print(x)
x = 33333
x=222
f3() # UnboundLocalError: local variable ‘x‘ referenced before assignment
# 定义函数的时候,print(x)中x是局部作用域中的x,但是在调用的时候,x还没定义,也不能向上查找,所以报错,无法执行。
(三)作用域
1.全局作用域
# 全局作用域:内置名称空间、全局名称空间
# 全局存活、全局有效
2.局部作用域
# 局部作用域:局部名称空间
# 临时存活,局部有效
(四)函数的参数传递都是值拷贝
# 示范1:对全局定义的不可变类型,不可以在函数内直接修改
x = 10
def func(a): # a=10的内存地址
a = 123
func(x) # x=10的内存地址
print(x) # 10
# 示范2:对全局定义的可变类型,可以在函数内直接修改
x = []
def func(a): # a=列表的内存地址
a.append(11111)
# a=123
func(x) # x=列表的内存地址
print(x) # [11111]
# 示范3:在函数内修改全局的不可变类型
x = 10
l = []
def func():
global x
x = 666
l.append(1111)
func()
print(x) # 666
print(l) # [1111]
# 示范4:nonlocal(了解)
x = 10
def f1():
x=11
def f2():
# global x
nonlocal x
x=66666
f2()
print("f1内的x===》",x)
f1() # f1内的x===》 66666
print(x) # 10
三、闭包函数
(一)什么是闭包函数
闭包函数,即函数对象+函数嵌套定义+名称空间与作用域。
闭:指的是定义函数内的函数。
包:指的内函数引用了外函数的变量。
def outter():
x = 1111
def inner():
print(x)
return inner # 千万不要加括号
f = outter()
# print(f) # <function outter.<locals>.inner at 0x000001ACE6E79040>
def f3():
x=222222
f()
f3() # 1111
(二)为函数体代码传参的两种方式
1.方式一:直接通过参数的方式传入
def func(x):
print(x)
func(1)
func(2)
func(3)
2.方式二:通过闭包函数传入
def outter(x):
# x = 2
def func():
print(x)
return func # 一定不要加括号
f1 = outter(1)
f2 = outter(2)
f3 = outter(3)
f1()
f2()
f3()
以上是关于013.Python之函数嵌套名称空间与作用域闭包函数的主要内容,如果未能解决你的问题,请参考以下文章
python基础之====函数对象函数嵌套名称空间与作用域装饰器
函数对象,函数的嵌套,名称空间与作用域,闭包,装饰器,迭代器,内置函数
函数嵌套 ,名称空间与作用域 ,闭包函数 ,装饰器 ,迭代器, 生成器 三元表达式,列表解析,生成器表达式 递归与二分法, 内置函数