函数对象、函数嵌套以及名称空间与作用域
函数对象、函数嵌套以及名称空间与作用域
一 函数对象
1 函数对象是什么
函数对象指的是函数可以被当成变量去使用。
def foo():
print('from foo')
print(foo) # <function foo at 0x00000215D4F95F70>
# 函数名就是一个内存地址
2 函数对象如何使用
2.1 函数对象可以被赋值
f = foo
print(f is foo) # True
f() # from foo
2.2 函数对象可以当作参数传给一个函数
def bar(func):
print(func)
func()
bar(foo) # <function foo at 0x0000014936EE5EE0>
# from foo
2.3 函数对象可以当成函数的返回值
def bar(func):
return func
res = bar(foo)
print(res) # <function foo at 0x000001FEF84C5EE0>
2.4 函数对象可以当成容器类型的一个元素
l = [foo]
print(l) # [<function foo at 0x0000023FB8685F70>]
l[0]() # from foo
# 示例:
def login():
print('登录功能')
def register():
print('注册功能')
def transfer():
print('转账功能')
def charge():
print('充值')
def withdraw():
print('提现')
func = {
"1": ("登录",login),
"2": ("注册",register),
"3": ("转账",transfer),
"4": ("充值",charge),
"5": ("提现",withdraw)
}
while True:
print("0 退出")
for k,v in func.items():
print(k,v[0])
choice = input("请输入你的操作编号:").strip()
if choice == "0":
break
if choice in func:
func[choice][1]()
else:
print("输入的指令不存在")
二 函数嵌套
1 函数嵌套的定义及特点
### 1.定义
函数嵌套就是一个函数在运行是调用了另一个函数。
def bar():
print('from bar')
def foo():
print('from foo')
bar()
foo() # from foo
# from bar
### 2.特点
正常情况下只能在函数体内部被调用。
# 案例:
from math import pi
def circle(radius, mode=0):
def perimiter(radius):
return 2 * pi * radius
def area(radius):
return pi * (radius ** 2)
if mode == 0:
return perimiter(radius)
elif mode == 1:
return area(radius)
res1 = circle(3, 0)
res2 = circle(3, 1)
print(res1)
print(res2)
2 函数嵌套的调用
def bar():
print('from bar')
def foo():
print('from foo')
bar()
foo() # from foo
# from bar
# 案例:
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)
print(res3)
max4(1, 2, 3, 4)
三 名称空间与作用域
1 名称空间
名称空间就是存放名字与对象映射关系的地方。在python程序运行的时候有三种名称空间。
1.1 内置名称空间及其生命周期:
存放python内置名字的地方。
生命周期:解释器启动时产生,解释器关闭则消失。
1.2 全局名称空间及其生命周期:
存放顶级名字的地方。
生命周期:python程序运行时产生,python程序结束时销毁。
# foo = 内存地址
def foo(): # foo本身也是全局的
z = 111
# f1 = 内存地址
def f1(): # f1是属于局部的
pass
if True: # if语句是全局的
aaa = 33
1.3 局部名称空间及其生命周期:
存放函数内部名字的地方。
生命周期:调用函数时产生,调用结束时销毁。
1.3 名字查找的优先级:
从当前位置往外查找,如果当前在局部:局部名称空间——》全局名称空间——》内置名称空间。
从当前位置往外查找,如果当前在全局:全局名称空间——》内置名称空间。
1.5 注意:嵌套关系的确定阶段
名称空间的嵌套关系,是在函数定义阶段就确定的,与函数的调用位置无关。
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还没定义,也不能向上查找,所以报错,无法执行。
2 作用域
2.1 全局范围/全局作用域及其特点:
全局作用域 = 内置名称空间 + 全局名称空间。
特点:全局存活,全局有效。
2.2 局部范围/局部作用域及其特点:
局部作用域 = 局部名称空间
特点:临时存活,局部有效。
2.3 了解global与nonlocal
#### (1) global
global就是声明变量是全局作用域下的变量。
x = 10
def func():
global x
x = 22
func()
print(x) # 22
#### (2) nonlocal
nonlocal就是声明变量是来自局部作用域下的外层函数。
x = 10
def f1():
x = 111
def f2():
nonlocal x
x = 222 # nonlocal之后,把外层函数的x改成了222,所以调用f1()打印出来的是f2
f2()
print(x)
f1() # 222

浙公网安备 33010602011771号