函数对象
-
函数名是可以被引用:
def index():
print('from index')
a = index #函数名赋值给a。
a() #执行a -
函数名可以当做参数传递
def foo(x, y, z):
print(x, y)
z()
def bar():
print('from bar')
foo(1, 2, bar) # bar = z, z()=bar(),打印:from bar -
函数名可以当作返回值使用
***传参的时候没有特殊要求,一定不要加括号,加括号当场执行。
def index(): #第一步:定义函数没有执行
print('from index')
def func(a): #第二步:定义函数
return a #第五步:输出from index
a = func(index) #第三步执行a,index = a
a() #第四步执行a,相当于index(). -
函数名可以被当作容器类型的元素
def func():
print('from func') #函数定义,没有执行
l1 = [1, 2, 3, func, func()] #func()直接执行,打印:from func
f = l1[3] #func的出的时他的地址
print(f)
输出结果:
from func
<function func at 0x000001F8D7B63948>
函数的嵌套
-
函数嵌套定义:在函数内部定义一个函数
-
函数嵌套调用:在函数内部调用函数
def func1(x,y):
if x > y:
return x
else:
return y
print(func1(1,2))
def func2(x, y, z, a):
result = func1(x, y)
result = func1(result, z)
result = func1(result, a)
return result
print(func2(1, 200000, 3, 1000))
名称空间
-
什么是名称空间?
存放名字的空间
如果你想访问一个变量值,必须先向对方的名称空间,拿到名字和对应的内存地址的绑定关系
-
名称空间的分类:
1、内置名称空间:
python提前给你的定义完的名字,就是存在于内置名称空间
2、全局名称空间
存放于文件级别的名字,就是全局名称空间
if while for 内部定义的名字执行之后都存放于全局名称空间
3、局部名称空间
函数内部定义的所有名字都是存放与当前函数的内置名称空间
生命周期:
1、内置名称空间
在python解释器启动的时候生效,关闭解释器的时候失效
2、全局名称空间
当你启动当前这个py文件的时候生效,当前页面代码执行结束之后失效
3、局部名称空间
当你调用当前函数时生效,函数体最后一行代码执行结束就失效名称空间的查找顺序:
查找顺序
-
名称空间的查找顺序:
-
局部:局部 > 全局 > 内置
-
全局:全局 > 内置 # 内置再找不到就报错
函数内部使用的名字,在定义阶段已经规定死了,与你的调用位置无关
x = 111
def func1(): #第一步
x = 222
def func2(): #第三步
x = 333
def func3(): #第五步
x = 444
def func4(): #第七步
x = 555 #第八步
print(x)
print('from func4')
func4() #第八步
func3() #第六步
func2() #第四步
func1() #第二步x = 111 #是全局变量
def index():
def wrapper():
print(x)
return wrapper #wrapper函数是在局部名称空间,
# return结束函数就没有内容了
index()
f = index()
f()
作用域
-
作用域的分类:
1、全局作用域
全局可以调用的名字就存在于全局作用域
内置名称空间+全局名称空间
2、局部作用域
局部可以调用的名字就存放与局部作用域
局部名称空间
-
global:声明全局变量
-
nonlocal:在局部名称空间声明局部变量,在局部修改上层函数的变量
-
只有可变类型可以在局部修改外部变量的值
golbal 全局变量使用
x = 1
def index():
global x #声明全局变量,使x = 2与x = 1在同一个级别,
#1先赋值给x,2又赋值给x。
x = 2
index()
局部变量的修改无法影响上层,上上层
def index():
x = 1
def index2():
# nonlocal x
x = 2
index2()
print(x)