名称空间
存放名字和对象映射关系的地方。
内置名称空间
就是解释器自带的一些名字
全局名称空间
伴随着python文件的执行,第二个被加载的空间
import sys #模块名sys
x=1 #变量名x
if x == 1:
y=2 #变量名y
局部名称空间
伴随函数的调用/结束而临时产生/回收,函数的形参、函数内定义的名字都会被存放于该名称空间中
def foo(x):
y=3
作用域
全局作用域与局部作用域
全局作用域:位于全局名称空间、内置名称空间中的名字都是属于全局范围。
局部作用域:位于局部名称空间的名字都属于局部范围。
作用域查找顺序优先级
在局部作用域查找名字时,起始位置是局部作用域,所以先查询局部名称空间,没有找到再去全局作用域找,先查找全局名称空间,没有找到,再去查找内置名称空间,最后都没有找到就抛出异常
x=100
def index():
x=200
index()
print(x)#输出结果是200
可以用内置函数locals()和globals()来分别查看局部作用域和全局作用域的名字,查看结果是字典格式。在全局作用域查看到的locals()相当于globals()
函数嵌套
def index():
x=1
def index1():
print(x)
index1()
index()
若在函数内修改全局名称空间名字的值,当值为不可变时,需要用到global关键字
x=1
def index():
global x
x=2
index()
print(x)#x结果为2
若是可变类型,则不需要使用global关键字,直接在原值上改
l=[1,2,3,4]
def index():
l.append(5)
index()
print(l)#[1, 2, 3, 4, 5]
对于多层嵌套的函数,使用nonlocal关键字可以将名字声明为来自外部嵌套函数定义的作用域
x=1
def index():
x=2
def func():
nonlocal x
x=3
func()
print(x)#3
index()
nonloacl x会从当前函数的外层函数一层层查找x,若是一直到外层函数都找不到,就会抛出异常。
函数对象与闭包
函数可以被当成变量赋值
def index():
return 123
res=index()
print(res)#123
函数可以被当成函数的实参
def index():
print('index')
return 123
def func(a):
print(a) #123
func(index())
函数名可以被当成函数的返回值
def index():
print('index')
return 123
def func():
pass
return index()
print(func())#123
函数名可以当成容器类型的元素
def index():
pass
return 5
l=[1,2,3,4,index()]
print(l)#[1, 2, 3, 4,5]
函数嵌套调用
def my_max(a,b): #比较两个数大小
if a>b:
return a
return b
#比较多个数大小
def func(a,b,c)
res=my_max(a,b)
res1=my_max(res,b)
return res1
max=func(1,2,3)
print(max)
闭包函数
什么是闭包函数?
闭:就是函数嵌套函数,至少有两层函数
包:内部的函数要使用外部函数中的名字
同时满足以上两种条件,才称为闭包函数
def outter():
x=1
def index():
print(x)
index()
outter()
#使用闭包函数实现比较数的大小
def outter(a,b):
def index():
if a>b:
return a
return b
return index
res=outter(1,2)
print(res())