global 方法
我们来看下面这段代码:
b = 100
def func():
b = b + 1
return b
print(func())
这段代码看上去中规中矩,似乎没有什么问题,但是程序运行后确报错。
这是因为在 Python 中,不允许直接在局部空间修改全局变量。b = b + 1 是一个冲突的语句:等式右边的 b 是要调用一个全部变量,而等号右边却是要定义一个局部变量。
如果将 b 视作一个全局变量依然不合适。在函数中修改全局变量会对其他调用相同变量的函数造成影响,除非万不得已或者十分确定的情况下,不建议在函数中修改全局变量。
当我们确定需要在函数中修改全局变量时,可以通过 global 方法来实现:
b = 100
def func():
global b
b = b + 1
return b
print(func())
【python函数教程(global 和 nonlocal的详细用法)】输出的结果为:
101
如果 global 声明的变量在全局空间中不存在,将会在全局空间中新建一个变量:
def func():
global a
a = 10
a = a + 12
print(a)
func()
print(a)
输出的结果为:
22
22
nonlocal 方法
对于回环嵌套的函数来说,也会有类似的问题。当尝试使用内层函数修改外层函数的变量时会报错:
a = 15
def func():
a = 10
def foo():
a = a + 1
foo()
print(a)
func()
print(a)
类似地,也不建议在内层函数中修改外层函数的变量。如果一定要修改的话,可以使用 nonlocal 方法:
a = 15
def func():
a = 10
def foo():
nonlocal a
a = a + 1
foo()
print(a)
func()
print(a)
输出的结果为:
11
15
nonlocal 方法只修改离它最近的一层函数的变量,如果这一层没有就往上一层查找,只能在局部查找。另外,外层函数不能调用内层函数的变量,即便用 nonlocal 方法也不行。如果外层所有函数中都没有声明的变量,即便全局空间中有也不行,而且 nonlocal 不能创建变量。如果找不到,就会报错:
a = 15
def func():
def foo():
nonlocal a
a = a + 1
foo()
func()
print(a)
其实想来这个设定也是合理的:如果外面套了很多层函数,这个变量该在哪一层创建呢?
global 和 nonlocal方法总结
global 只修改全局空间中存在的变量
在局部空间中可以使用全局中的变量,但是不能修改。如果要强制修改,需要使用 global 声明
当变量在全局存在时,global 就是声明我要修改全局的变量
当变量在全局中不存在时,global 则是声明要在全局创建一个变量
nonlocal 只修改局部空间中的变量,最多只能到达最外层函数
在内层函数中可以使用外层函数中的变量,但是不能修改。如果要强制修改,需要使用 nonlocal 声明
只修改离 nonlocal 最近的一层,如果这一层没有就往上一层查找,不能找到全局中
nonlocal 不能创建变量,如果其声明的变量在外层函数中找不到,即便全局空间中有,也会报错
对函数的传参有一点补充,传参的时候相当于在当前函数体中进行了赋值操作:
def func(a):
# 相当于在func函数体中写了这么一个 a = 100 操作
print(locals())
func(100)
最后来一道思考题,请确定下列函数输出的结果:
a = 10
def func():
a = 5
def foo():
a = 3
def f():
nonlocal a
a = a + 1
def aa():
a = 1
def b():
global a
a = a + 1
print(a)
b()
print(a)
aa()
print(a)
f()
print(a)
foo()
print(a)
func()
print(a)
以上就是本次分享的全部内容,现在想要学习编程的小伙伴欢迎关注Python技术大本营,获取更多技能与教程。
文章图片
推荐阅读
- Python教程(os 与 sys 模块详细用法)
- #|k近邻算法实现--Knn
- python机器学习|从零到一实现神经网络(五):数学微分法更新权重参数
- #|Django models.py 表结构数据更新后应用到数据库中
- python|python 深度 视差 计算_开源双目视觉BM算法-Matlab/Python/Javascript
- OpenCV|解决error: (-215:Assertion failed) _src.empty() in function ‘cv::cvtColor‘
- 树莓派|Python3树莓派连接阿里云物联网设备发送接收数据
- 树莓派|【树莓派】树莓派4无痛安装系统(NOOBS篇)
- Anaconda|记录一次pyinstaller打包出现的问题