百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

看一看,Python这四种作用域你都知道吗?

myzbx 2025-07-17 22:54 23 浏览

点赞、收藏、加关注,下次找我不迷路

一、啥是作用域?先打个比方

比如说,你在自己的卧室(相当于一个小空间)里放了一本书,这本书在卧室里随便你怎么看,这就是这本书在卧室这个 "作用域" 内有效。但如果你走到客厅(另一个空间),想找这本书就找不到了,因为它的作用域只在卧室。在 Python 里,作用域其实就是变量能够被访问的范围,也就是变量的 "活动范围"。


二、Python 作用域的四种类型

Python 中有四种作用域,分别是局部作用域(Local)、全局作用域(Global)、嵌套作用域(Enclosing)和内置作用域(Built - in)。接下来咱们一个一个详细说,每个都配上简单的例子。

(一)局部作用域(Local)

局部作用域就像是一个 "小圈子",一般指的是函数内部的作用域。在函数里面定义的变量,只能在这个函数里面用,出了这个函数,就像从这个小圈子里出去了,就找不到这个变量了。

def my_function():
    local_var = 10  # 这是局部变量,只在my_function函数里有效
    print("函数内局部变量:", local_var)

my_function()  # 输出:函数内局部变量:10
# print(local_var)  # 这行代码会报错,因为local_var在函数外不存在


就好比你在自己的小房间(函数)里养了一只宠物,这只宠物只在你的小房间里活动,出了房间就看不到它了。

(二)全局作用域(Global)

全局作用域就像是一个 "大广场",在整个文件(模块)中都有效,也就是说,在函数外部定义的变量,整个文件里的函数都可以访问它(但要注意修改的问题,后面会讲)。

global_var = 20  # 这是全局变量,在整个文件中有效

def my_function1():
    print("函数1访问全局变量:", global_var)

def my_function2():
    print("函数2访问全局变量:", global_var)

my_function1()  # 输出:函数1访问全局变量:20
my_function2()  # 输出:函数2访问全局变量:20

这就相当于广场上有一个公共设施,不管你在广场的哪个角落(哪个函数),都能看到并使用它。

(三)嵌套作用域(Enclosing)

嵌套作用域是指在一个函数里面再定义一个函数,里面的函数(内层函数)可以访问外层函数定义的变量,但外层函数不能访问内层函数的变量。这就像是一层套一层的盒子,内层盒子可以看到外层盒子里的东西,外层盒子看不到内层盒子里的东西。

def outer_function():
    outer_var = 30  # 外层函数的变量
    def inner_function():
        inner_var = 40  # 内层函数的变量
        print("内层函数访问外层变量:", outer_var)  # 可以访问外层变量
    inner_function()
    # print(inner_var)  # 这行代码会报错,外层函数不能访问内层变量

outer_function()  # 输出:内层函数访问外层变量:30


就像你在一个大盒子里放了一个小盒子,小盒子能看到大盒子里的东西,但大盒子看不到小盒子里的东西。

(四)内置作用域(Built - in)

内置作用域是 Python 预先定义好的作用域,里面包含了所有的内置函数和内置变量,比如 print、len、list 等,在整个程序中都可以直接使用,不需要额外定义。

print("内置函数len的使用:", len([1, 2, 3]))  # 直接使用内置函数len,输出3

这就好比 Python 给我们准备了一套 "通用工具",我们在任何时候都可以拿过来用。

为了让大家更清楚地对比这四种作用域,咱们做个表格:

作用域类型

定义位置

有效范围

示例

局部作用域(Local)

函数内部

仅在函数内部

def f(): a=10

全局作用域(Global)

函数外部

整个文件(模块)

b=20def f(): print(b)

嵌套作用域(Enclosing)

外层函数内部

外层函数及内层函数

def outer(): c=30 def inner(): print(c)

内置作用域(Built - in)

Python 内置

整个程序

print(len([1,2,3]))


三、变量查找顺序:LEGB 原则

当我们在代码中使用一个变量时,Python 会按照 LEGB 的顺序来查找变量,LEGB 就是这四种作用域英文首字母的缩写,顺序是:Local(局部作用域)→ Enclosing(嵌套作用域)→ Global(全局作用域)→ Built - in(内置作用域)。也就是说,先在当前的局部作用域找,如果找不到,就到外层的嵌套作用域找,再找不到就到全局作用域找,最后到内置作用域找,如果都找不到,就会报错。

built_in_var = "内置变量"  # 内置作用域其实是Python预定义的,这里只是模拟

global_var = "全局变量"

def outer():
    enclosing_var = "嵌套作用域变量"

    def inner():
        local_var = "局部变量"
        print(local_var)  # 先找局部作用域,找到,输出:局部变量
        print(enclosing_var)  # 局部没有,找嵌套作用域,找到
        print(global_var)  # 嵌套没有,找全局作用域,找到
        print(built_in_var)  # 全局没有,找内置作用域(这里模拟的,实际内置作用域是Python自带的)

    inner()

outer()

通过这个例子,大家可以清楚地看到变量查找的顺序。


四、修改全局变量和嵌套作用域变量:global 和 nonlocal 关键字

(一)修改全局变量:global 关键字

前面咱们说过,在函数内部可以访问全局变量,但如果想在函数内部修改全局变量,就需要使用 global 关键字声明,否则 Python 会认为你在函数内部定义了一个新的局部变量。

global_num = 10

def change_global():
    # global global_num  # 不声明的话,下面这行代码会报错
    global_num = 20  # 报错,因为没有声明global,Python认为这是局部变量赋值,而之前没有定义这个局部变量

# change_global()  # 运行会报错

# 正确的做法:
def change_global_correct():
    global global_num
    global_num = 20

change_global_correct()
print(global_num)  # 输出:20

就像你想修改广场上的公共设施,得先告诉大家你要修改的是公共的,而不是自己弄一个新的。

(二)修改嵌套作用域变量:nonlocal 关键字

在内层函数中,如果想修改外层函数的变量,需要使用 nonlocal 关键字声明,否则会被认为是在内层函数中定义了一个新的局部变量。

def outer_nonlocal():
    outer_num = 30

    def inner_nonlocal():
        # nonlocal outer_num  # 不声明的话,下面这行代码会报错
        outer_num = 40  # 报错,因为没有声明nonlocal,Python认为这是内层函数的局部变量赋值

    # inner_nonlocal()  # 运行会报错

    # 正确的做法:
    def inner_nonlocal_correct():
        nonlocal outer_num
        outer_num = 40

    inner_nonlocal_correct()
    print("修改后的外层变量:", outer_num)  # 输出:修改后的外层变量:40

outer_nonlocal()

这就好比内层盒子想修改外层盒子里的东西,得先告诉系统自己要修改的是外层的变量,而不是自己内部的新变量。


五、这些情况需要注意

(一)局部变量和全局变量同名的情况

当局部变量和全局变量同名时,在函数内部,局部变量会覆盖全局变量,也就是说,在函数内部使用的是局部变量,函数外部使用的是全局变量。

name = "小明"  # 全局变量

def say_hello():
    name = "小红"  # 局部变量,和全局变量同名
    print("函数内:", name)  # 输出:函数内:小红

say_hello()
print("函数外:", name)  # 输出:函数外:小明

这就像是在小房间里有一个和广场上同名的物品,在小房间里用的是小房间里的物品,出了小房间还是用广场上的。

(二)内置作用域的变量不要轻易修改

内置作用域中的变量,比如 list、dict 等,是 Python 内置的函数或类型,不要轻易给它们赋值,否则会导致内置函数无法正常使用。

# 错误示例
list = [1, 2, 3]  # 给内置函数list赋值,导致后面无法使用list()函数
new_list = list([4, 5, 6])  # 会报错,因为此时list是一个列表,不是函数

# 正确做法:不要给内置函数名赋值

(三)嵌套作用域的层数

虽然 Python 支持多层嵌套函数,但不建议写太多层嵌套,因为这样会让代码变得复杂,可读性差,也容易出现作用域相关的问题。


简单总结一下:

  • 局部变量:函数内定义,函数内使用。
  • 全局变量:函数外定义,整个文件可用,修改需 global。
  • 嵌套作用域:内层函数可访问外层变量,修改外层变量需 nonlocal。
  • 内置作用域:Python 自带,直接使用。
  • 变量查找:按 L→E→G→B 的顺序找。

希望这篇文章能让你对 Python 作用域有一个清晰的认识,在编程的道路上更进一步!如果还有不明白的地方,欢迎在评论区留言哦!

相关推荐

OPPO Find X9手机曝料:6.6英寸屏幕、天玑9500芯片

IT之家8月27日消息,科技媒体xpertpick今天(8月27日)发布博文,报道称OPPO计划于今年10月推出FindX9系列旗舰手机,其中包括FindX9和...

OPPO Find X9系列搭载影像新硬件,支持Ultra级画质和色彩还原

IT之家8月27日消息,OPPOFindX9系列手机发布时间逐渐临近,目前官方已开启新机的前瞻预热。OPPOFind系列产品负责人周意保今日发文解释了厂商为什么现在都喜欢跨界合作这一...

我回来了!聊聊屏幕对续航的影响_屏幕耗电吗

时隔一周终于回国,让大家久等了本来上周日就能到家,结果在旧金山转机的时候把护照弄丢了…幸好后来被一位黑人大姐找到了,才能顺利回国,感谢勤劳朴实的美利坚人民。出差途中笔记本的续航是很重要的,刚好联想的产...

J人福音、P人救星,Lumix Flow如何重塑专业视频拍摄工作流

“等一下,刚才那个中景拍了没有?”“A机位的素材是哪一场的?”“完了,我忘了记哪一条是最好的了!”“今晚加个班,先把能用的素材挑出来……”作为经常一个人拍视频的内容创作者,这种崩溃称得上习以为常。如果...

realme史上最窄边框和下巴 realme GT Neo3正式发布

中关村在线消息:今天下午14点,realme召开真我GTNeo3发布会。realmeGTNeo3搭载6.7英寸2412×1080OLED直屏,其支持120Hz刷新率,360Hz触控采样率,智能...

用酒精擦屏幕,对屏幕的伤害有多大?

天府新青年你触手可及的朋友圈附录:1.不是所有电脑的屏幕都不能用酒精来擦,通常来说只有镜面屏屏幕才有涂层,这种不能用酒精擦;而雾面屏用的是另外一种抗反射技术,这种一般擦了没事。镜面屏和雾面屏特别好认...

windows11截屏快捷键是哪个?windows11快捷键设置大全

windows11键盘快捷方式就是键盘快捷方式就是按键或按键组合,可提供一种替代方式来执行通常使用鼠标执行的操作。下面就来分享下windows11截屏快捷键是哪个和windows11快捷键设置大全。一...

三星Galaxy S25 Slim配置曝光 6.7英寸屏幕搭配2亿像素主摄

【CNMO科技新闻】三星GalaxyS25系列将于北京时间1月23日正式发布,CNMO注意到有博主爆出了即将亮相GalaxyS25Slim的配置信息。据悉,GalaxyS25Slim将配备一...

两种手机屏幕到底有什么不一样?哪种手机屏幕更好?

一般来说,我们的手机屏幕只分为两种OLED和LCD,LCD是大火的一种手机屏幕,是千元机以及高端机的标配,OLED算是后起之秀,是近几年才渐渐兴起的一种类型的手机屏幕,那么这两种手机屏幕到底有什么不一...

有强芯才好用 这三款高性价比旗舰芯热机最低仅需1799元

在选购手机时,相信大家肯定都会把性能作为考虑的重点之一。而如果希望拥有出色的性能表现,一颗旗舰处理器是必不可少的。今天我就为大家汇总了几款采用旗舰处理器的底价新机,感兴趣的朋友千万不要错过。moto...

一文搞定FastDFS的搭建和使用_fastdfs怎么样

1.FastDFS概述FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文...

涨姿势!超级计算机用啥文件系统呢?

2015-10-1705:58:00作者:赵为民在计算机中,文件系统(filesystem)是一个非常重要的组件,你可以将他看做是操作系统的子系统,其实质就是一种软件的组件,通过文件系统我们可以...

Window as a VM:Chrome OS 现可窗口化运行其它 Linux 分支

这世上纵然有多种办法可以在Chromebook上安装运行ChromeOS和其它Linux分支多系统,但如果无需重启通过引导切换,确实是个很酷的改进。Google布道师Francois...

Win10新预览版19577开始推送:新图标+多项新功能

今日凌晨,微软正式向Windows10Insider快速通道用户推送了全新版本Windows10——Windows10InsiderPreviewBuild19577。19577版本是...

微软Windows升级密钥(例如家庭版升级为企业版)

下面的密钥,是微软官方提供的,仅能用于Windows10系统版本的升级,比如从家庭版升级为专业版、专业版升级为企业版等。升级密钥不能用于激活系统,激活需要KMS或者数字权利,由于涉及到版权问题,在此不...