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 国际」许可协议进行许可。
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现