python全栈学习记录(十二)函数的名称空间与作用域

函数的名称空间与作用域

一、函数的名称空间

所谓名称空间就是存放名字与值绑定关系的地方。
名称空间可以分成三类:

  • 内置名称空间:
    作用:存放python解释器自带的名字
    生命周期:在解释器启动时生效,在解释器关闭时失效

  • 全局名称空间:
    作用:除了内置的与局部的名字外,其余都是全局名字
    生命周期:在文件执行时生效,在文件执行完毕时失效

  • 局部名称空间:
    作用:用于存放函数调用期间函数体产生的名字
    生命周期:如果调用了某个函数才会临时生效,在函数执行完毕后失效

三种名称空间的加载顺序是:内置-》全局-》局部
三种名称空间的查找顺序是:局部-》全局-》内置

print(dict)#内置名称空间首先加载,所以第一个print打印dict类
dict=11
print(dict)#dict在全局名称空间被覆盖,所以打印1
dict('a'=1)#由于dict已经变为了全局名称空间的数字类型,所以无法在使用字典的功能
<<< <class 'dict'>
<<<11
<<<报错
a=12
def func():
	a=1
	print(a)#局部名称空间中a的值为1,所以打印1
print(a)#由于此处不在func函数的名称空间内,所以找到全局名称空间的a,也就是12
func()
<<<12
<<<1

二、函数的作用域

域的意思是区域、范围,作用域即作用的范围。
全局作用范围,全局作用域(内置名称空间与全局名称空间)
局部作用范围,局部作用域(局部名称空间)

作用域关系是在函数定义阶段就固定死了,但凡调用函数都需要跑到定义阶段去找作用域关系

x=1
def f1():
    print(x)
x=1000000000000000000000000000000000000000000000000000000000000000
def f2():
    x=11111111111111111111111111111
    f1()
f2()
<<<1000000000000000000000000000000000000000000000000000000000000000

上面的代码中,即便在f2函数中修改了x的值,但是当f1定义阶段结束f1函数的作用域已经定下了,其查找顺序为f1的内部名称空间,全局名称空间,与f2内部的名称空间没有任何关系。

a=10
def func():
	b=a+1
	a=20
	print(a,b)
func()
<<< UnboundLocalError: local variable 'a' referenced before assignment

当func函数内出现对变量a的赋值时,a在函数定义阶段就会被当做局部变量处理。当函数运行时,b=a+1而局部变量a还未被赋值,所以报错了。若要解释器把a当作全局变量处理,可以加上global关键字。

a=10
def func():
	global a
	b=a+1
	a=20
	print(a,b)
func()
<<<20 11

需要注意的是只有在函数内修改变量的值时,解释器才会把这个变量的作用域定在函数的局部名称空间内。但是当我们去修改可变类型值时,一般修改的是可变类型内部的值,而不是修改变量与可变类型的绑定关系,所以函数内部修改了值也会影响到处于全局中的可变类型。

a=1
b=[1]
def func():
	a=100 #修改变量a的值
	b.append(2) #给列表b增加值,换句话说就是列表b自身的id没有改变,只是列表b内存放的地址多了一个
	print(a,b)
func()
print(a,b)
<<<100 [1,2]
<<<1 [1,2]

nonlocal函数可以将变量声明为来自上一级的局部名称空间,但是不能到全局名称空间,不然会报错

def b():
    a=9
    def g():
        nonlocal a #nonlocal将变量a声明到了b函数的局部名称空间中
        a=100
    g()
    print(a)
b()
<<<100
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值