python之变量作用域

一、前言

本节主要内容如下:
1.变量查找顺序
2.全局变量和局部变量
3.nonlocal关键字
4.global关键字和nonlocal关键字的区别:

二、变量查找顺序

函数作用域的LEGB顺序

1.什么是LEGB?

L: local函数内部作用域
E: enclosing函数内部与内嵌函数之间
G: global 全局作用域
B: build-in内置作用域

2.他们是做什么用的?

为什么非要介绍这个呢?或者说他们的作用是什么?
原因是因为我们的在学习python函数的时候,经常会遇到很多定义域的问题,全局变量、局部变量、内部嵌入的函数,等等,
python是如何查找的呢?以及python又是按照什么顺序来查找的呢?这里做一个顺序的说明

3.顺序是什么?

跟名字一样,python在函数里面的查找分为4种,称之为LEGB,也正是按照这种顺序来查找的。
首先,是local,先查找函数内部
然后,是enclosing,再查找函数内部与嵌入函数之间(是指再函数内部再次定义一个函数)
其次,是global,查找全局
最后,是build-in,内置作用域

三、全局变量和局部变量

全局变量是在整个py文件中声明,全局范围内都可以访问

局部变量是在某个函数中声明的,只能在该函数中调用它

我们来看一个小例子:


name = 'chuan'

def func():
    name = 'boy'
    print('函数内部',name)

func()
print('函数外部',name)

#打印结果:
# 函数内部 boy
# 函数外部 chuan

这里,函数内部的name就是全局变量,函数外部的name就是局部变量
注意:这里有一个问题,我们想函数内部有一个变量name,函数外部也有一个变量name,那么当我在函数内部使用变量name的时候,它是按照什么规则取的name呢?其实,这里就用到了上面说的变量的查找顺序。

1.查看全局变量和局部变量:

name = 'chuan'

def func():
    name = 'boy'
    print('函数内部',name)
    print(locals())  #查看局部变量
    print(globals()) #查看全局变量

func()

#打印结果:
# 函数内部 boy
# {'name': 'boy'}
# {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000018E0CA74288>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Program Files/python老男孩/Day15/01全局变量和局部变量.py', '__cached__': None, 'name': 'chuan', 'func': <function func at 0x0000018E0E6C4678>}

从上面的打印结果,我们就可以看到,局部变量name=‘boy’,
全局变量中可以找到name = ‘chuan’。

注意:这里的是在函数内部使用的locals()和globals()函数,如果是在函数外部使用,就不一样了,函数的局部变量和全局变量是一样的。

2.函数内部使用全局变量,只能查看,不能修改

name = 'chuan'

def func():

    print('函数内部',name)
func()
#打印结果是:
#函数内部 chuan

我们看到,我们是可以直接查看全局变量name的

name = 'chuan'

def func():

    print('函数内部',name)  #这里的name会报错
    name = 'xixi'
func()

为什么这里的name会报错呢?因为当你在函数内部写name=‘xixi’,
编译器就会认为你定义了一个局部变量name,而print(‘函数内部’,name)是在name声明之前使用,自然就会报错了

3.使用global在函数内部把变量声明为全局

NAME = '杠精'

def xi():
    global NAME#可以理解为是全局变量NAME的引用
    print(NAME) #打印结果说明,这个就是上面的全局变量NAME
    NAME = '小东北'  #修改全局变量
    print('我要做',NAME)
xi()
print(NAME)  
#打印结果:
#杠精
#我要做 小东北
#小东北

4.函数内部引用可变类型的全局变量

NAME = ['我','哎']

def xi():
    NAME.append('你')#此处拿到全局变量,无法对其就行重新赋值 NAME = 'fff' ,但可以添加元素
    # NAME = ['love']  无法重新赋值全局变量
    print('我知道',NAME)

xi()
#打印结果:
#我知道 ['我', '哎', '你']

5.一种易错情况

#
name = 'chuan'

def func():
    name = 'xixi'
    global name
    print('函数内部',name)

func()

这种,是会报错的。为什么呢?因为name= 'xixi’相当于声明了一个局部变量并赋值,但是我们又想把这个变量变成外部的全局变量的引用,显然这是不可能的。

四、nonlocal关键字

#2.关键字nonlocal,指定上一级变量
# NAME = '钢梁'
#
# def xi():
#     name = '机智'
#     def ha():
#         nonlocal name#指定上一级变量
#         name = '冷静'
#
#     ha()
#     print(name)
#
# print(NAME)
# xi()
# print(NAME)

五、global关键字和nonlocal关键字的区别

1.global可以用在任何地方,包括最上层函数中和嵌套函数中,即使之前未定义该变量,

def global_test():
    global gcount   #在之前未定义该变量
    gcount = 1
    print(gcount)
global_test()  #1

2.global修饰后也可以直接使用,而nonlocal关键字只能作用于嵌套函数中,并且外层函数中定义了相应的局部变量,nonlocal最多找到顶层的函数内局部变量,它不能找全局变量,否则会发生错误

name = 2
def haha():
    nonlocal name  #没有在嵌套函数内,不能找全局变量(外层嵌套函数没有这个变量自己不能单独定义使用,
                    # 且nonlocal最多找到顶层的函数内局部变量)
    name = 5
    print(name)
haha()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值