Loading

python局部和全局作用域

一、作用域及局部/全局变量:

  • 在被调用函数内赋值的变元和变量,处于该函数的“局部作用域”,处于局部作用域的变量,被称为“局部变量”;
  • 在所有函数之外赋值的变量,属于“全局作用域”,处于全局作用域的变量,被称为“全局变量”;
  • 全局作用域中的代码不能使用任何局部变量;
  • 局部作用域可以访问全局变量;
  • 一个函数的局部作用域中的代码,不能使用其他局部作用域中的变量;
  • 在不同的作用域中,可以用相同的名字命名不同的变量。也就是说可以有一个名为spam的局部变量、一个名为spam的全局变量。

二、注意事项:

  • 局部变量不能在全局作用域内使用
def spam():
    eggs = 31337
spam()
print(eggs)

如果运行这个程序,输出将是:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'eggs' is not defined

发生错误是因为,eggs变量只属于spam()调用所创建的局部作用域。在程序执行从spam返回后,该局部作用域就被销毁了,不在有名为eggs的变量。

  • 局部作用域不能使用其它局部作用域内的变量
复制代码
 1 def spam():
 2     eggs = 99
 3     bacon()
 4     print(eggs)
 5 
 6 def bacon():
 7     ham = 101
 8     eggs = 0
 9 
10 spam()
复制代码

在程序开始运行时,行号10中spam()函数被调用,创建了一个局部作用域。局部变量行号2中的eggs被赋值为99.然后行号3中的bacon()函数被调用,创建了第二个局部作用域。多个局部作用域能同时存在。在这个新的局部作用域中,行号7/8中的局部变量ham被赋值为101,局部变量eggs也被创建并赋值0。

当bacon()返回时,这次调用的局部作用域被销毁。程序执行在spam()函数中继续,行号4打印eggs的值。因为spam()调用的局部作用域依然存在,eggs变量被赋值为99。

一个函数中的局部变量完全与其他函数中的局部变量分隔开来。

  • 全局变量可以在局部作用域中读取
def spam():
    print(eggs)

eggs = 42
spam()
print(eggs)

因为在spam()函数中,没哟变量为eggs,也没有代码为eggs赋值,所以当spam()中使用eggs时,python认为他是对全局变量eggs的引用。这就是前面的程序运行时打印出42的原因。

  • 名称相同的局部变量和全局变量

 现实中要避免全局变量与其他局部变量同名。但在技术角度层面,python中让局部变量和全局变量同名是完全合法的

复制代码
#函数1
def  spam():
     eggs = 'spam local'
     print(eggs)  #print "spam local"

#函数2:
def  bacon():
     eggs = 'bacon local'
     print(eggs)  #print "bacon local"
     spam()
     print(eggs)  #print "bacon local"

#函数3
eggs = 'global'
bacon()
print(eggs)  #print "global"
复制代码

函数1名为eggs的变量,存在于spam()被调用时的局部作用域;

函数2名为eggs的变量,存在于bacon()被调用时的局部作用域;

函数3名为eggs的变量,存在于全局作用域。

 

三、global语句

如果需要在一个函数内修改全局变量,就使用global语句。

1 def spam():
2     global eggs
3     eggs = "spam"
4 
5 eggs = "global"
6 spam()
7 print(eggs)

因为eggs在spam()的顶部被生命为global,所以当eggs被赋值为‘spam’,赋值发生在全局作用域的spam上。没有创建局部spam变量。

4条法则,来区分一个变量是处于局部作用域还是全局作用域:

  • 如果变量在全局作用域中使用(即在所有函数之外),他就总是全局变量;
  • 如果一个函数中,有针对该变量的global语句,他就是全局变量;
  • 否则,如果该变量用于函数中的赋值语句,它就是局部变量;
  • 但是,如果该变量没有用在赋值语句中,它就是全局变量。

ex:

复制代码
#函数1:
def spam():
    global eggs
    eggs = 'spam' # this is  the global

#函数2:
def bacon():
    eggs = "bacon" # this is a local

#函数3:
def ham():
    print(eggs)  #this is the global


eggs = 42 #this is the global
spam()
print(eggs)
复制代码

在spam函数中,eggs是全局eggs变量,因为在函数的开始处,有针对eggs变量的global语句;

在bacon()中,eggs是局部变量,因为在该函数中有针对它的赋值语句;

在ham()中,eggs是全局变量,因为在这个函数中,既没有赋值语句,也没有针对它的global语句。

 

作者:solomon-zj

出处:https://www.cnblogs.com/solomon-zj/p/16559006.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   solomon-zj  阅读(251)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示