当前位置:首页>python>Python入门(番外篇):命名空间和作用域

Python入门(番外篇):命名空间和作用域

  • 2026-10-14 04:11:10
Python入门(番外篇):命名空间和作用域

很多时候,我们编写的代码出现莫名的错误,代码量多的情况下,排查非常困难。这主要是我们对命名空间、作用域的理解不够导致的。本文就用几个案例来直观展示下这类问题。

P 1、命名空间

什么是命名空间,有什么作用?

官方文件说:“namespace (命名空间)是从名称到对象的映射。一个命名空间的作用域是 Python 代码中的一段文本区域,从这个区域可直接访问该命名空间。”

白话就是无论一个.py文件、一个函数、一个类,或者一个文件夹,它自身就是一个命名空间,可以向下映射,互相隔离、无冲突。比如:files.py文件中的一个函数myfunc、一个变量myvar、一个类mycls等,都必须是唯一的名称。此时,函数、类可以再向下映射出各自的变量func_var、方法cls_func等,这些也都有自己的名字。这些名字要求,在任何的同级都不能出现重复,保证各个名称的隔离、唯一性,从而避免出现名称冲突。

如下的命名不会产生任何冲突:

files.myfunc.func_varfiles.myvarfiles.myclsfiles.mycls.cls_func

官方文件说:“一个命名空间的作用域是 Python 代码中的一段文本区域,从这个区域可直接访问该命名空间。”

先理解官方的解释:命名空间是在不同时刻创建的,且拥有不同的生命周期。内置名称的命名空间是在 Python 解释器启动时创建的,永远不会被删除。模块的全局命名空间在读取模块定义时创建;通常,模块的命名空间也会持续到解释器退出。函数的局部命名空间在函数被调用时被创建,并在函数返回或抛出未在函数内被处理的异常时,被删除。

P 2、作用域

什么是局部变量、全局变量、nonlocal变量?

上述这些,讲的都是变量或者命名空间在命名空间中的作用域。通过global、nonlocal关键字可以改变变量作用域,它们分别表示全局变量、外层变量。其中,global声明的变量是在外层所有命名空间中的某个地方定义的。而nonlocal声明的变量只是在外1层命名空间的某个地方定义。

(1)局部变量

num = 10def myfunc():    num = 20    print(f'myfunc.{num=}')myfunc()print(f'global.{num=}')

输出:

myfunc.num=20global.num=10

可以看到,函数内外部变量名称是一致的,但互不影响,各自发挥作用。

(2)全局变量
# 全局变量(两层空间)num = 10def myfunc():    global num    num = 20    print(f'myfunc.{num=}')myfunc()print(f'global.{num=}')
输出:
myfunc.num=20global.num=20

可以看到,由于global关键字的影响,两层命名空间下,函数内可以修改全局声明变量。

# 全局变量(三层空间)num = 10def outer():    def myfunc():        global num        num = 20        print(f'myfunc.{num=}')    myfunc()outer()print(f'global.{num=}')
输出:
myfunc.num=20global.num=20

可以看到,由于global关键字的影响,三层命名空间下,函数内可以修改全局声明变量。更多层也是一样的。

(3)nonlocal变量

# 非本地变量(三层空间)num = 10def outer():    def myfunc():        nonlocal num        num = 20        print(f'myfunc.{num=}')    myfunc()
输出:
  Cell In[14], line 5    nonlocal num    ^SyntaxError: nobinding for nonlocal 'num' found

直接定义出错,指示外层空间未定义num变量。修改下代码,在outer()函数空间定义num变量。

# 非本地变量(三层空间)num = 10def outer():    num = 15    def myfunc():        nonlocal num        num = 20        print(f'myfunc.{num=}')    myfunc()    print(f'outer.{num=}')outer()print(f'global.{num=}')
输出:
myfunc.num=20outer.num=20global.num=10

可以看到,每层空间都有num定义,但最内层函数myfunc()中,声明了nonlocal变量num,并修改为20,导致了外层函数outer()中定义的num发生了变化,同样输出了20。但全局定义的变量num值始终为10,保持不变。

☆☆☆ End ☆☆☆转角  ·  遇见  ·  程序猿
-------------------------
那是一抹淡淡的微光

它是数字世界里的一把杀猪刀

却总能巧夺天工

它的世界是纯粹0、1组合

却总能创造无尽幻想

......

本公众号关注数据价值分析、编程学习,将不定期更新社会热点数据分析结果、编程技巧,分享数据分析工具、方法、学习等内容,欢迎有兴趣的小伙伴加入。

最新文章

随机文章