一文看懂global, nonlocal, local变量
Python中,变量是根据程序运行顺序进行的,比如函数外的变量,在函数内是可见的,但是可用,不可赋值。那么如何实现赋值呢?
利用global关键字进行。
在函数内,如果出现和函数外的变量同名变量,而且对这个变量进行了赋值操作,这个变量是局部变量,只对函数内可见。如果没有赋值操作,函数访问的是函数外的变量,此时如果你修改该变量将会提示报错,提示你在用这个变量前先进行赋值:UnboundLocalError: local variable 'x' referenced before assignment
也就是说,变量如果在函数内赋值,则这个变量是局部变量。而如果没有赋值操作,又没有加global关键字,使用的是外部的变量。而如果想对来自函数外部的变量进行操作,那么需要加global关键字。
在python内部,解释器引用变量的顺序是:1. 函数内的变量,2. 包含函数的区域 3.包含这个函数模块 4. 系统常用的比如len, str
# In[]
'''
global
nonlocal
#local
'''
x=10
def fun():
print(x) fun()
# In[]
'''
result:
10000
10
here x is a local variable, it is visible just in the function of fun(). It
has no relationship with the x variable outside.
'''
x=10
def fun():
x=10000
print(x) fun()
print(x) # In[]
'''
result:
UnboundLocalError: local variable 'x' referenced before assignment you can do assignment to the variable x, and it will be a local variable.
here the sentence 'x=x+1' is assignment but the x has not initialization.
''' x=10
def fun():
x=x+1
print(x) fun()
此时如果你的本意是对外部的变量进行修改操作,你只需要将这个变量设为global即可。
x=10
def fun():
global x
x=x+1
print(x) fun()
print(x)
另外,在函数嵌套中,也存在类似的问题。函数嵌套,一个函数内有另外一个函数。外部函数内的变量,对内部的函数是可见的。
def fun(x):
def inner(y):
print(x+y)
return inner f = fun(10)
f(1)
但是内部函数对外部函数内的变量是否可以修改呢?下面的代码会返回错误信息:UnboundLocalError: local variable 'x' referenced before assignment
def fun(x):
def inner(y):
# nonlocal x
x=x+10
print(x+y)
return inner f = fun(10)
print(f)
f(1)
但是当你把nonlocal这行注释取消了,就没有任何问题了。此时代码运行结果为21,10,说明在内部函数inner实现了变量x的增值x=x+10操作。这里变量x使用的是外部函数传入的参数,可以从程序里看到,此时外部的变量x在执行外函数调用后,并没有发生变化。外面打印x时,依然是10,而只有函数内部发生了变化。在函数fun中,x变量就是一个传入的参数,和外部的全局变量不一样的。
'''
You can not do assignment with the parameter x above.
But you can do this below.And it is not the same with global because
the variable x outside do not change. The change just appear in the function.
'''
x=10
def fun(x):
def inner(y):
nonlocal x
x=x+10
print(x+y)
return inner f = fun(x)
f(1)
print(x)
如果我用这个代码来写,可能会更加清晰了。就是说这里的nonlocal其实有点类似于前面的global的作用,只是范围不一样,但是达到的目的类似,就是使得更内一层的函数可以改变。
x=10
def fun(a):
def inner(y):
nonlocal a
a=a+10
print(a+y)
return inner f = fun(x)
f(1)
print(x)
nonlocal这个关键字出现在python3.x中,在python2是没有的。在python2中,可以通过可变对象类型比如list, dict来实现,内部函数对外部函数的变量进行改变。
'''
But nonlocal appears in python 3.5 later. Without nonlocal you can only use
list or dict, these variables is not like integer or str which can not vary.
Here you are not doing assignment actually.
'''
def fun(lst):
def inner(y):
lst.append(y)
print(len(lst))
return inner
lst = []
f = fun(lst)
f(1)
f(2)
f(3)
f(4)
这种做法,和以下做法一样。
def fun():
lst = []
def inner(y):
lst.append(y)
print(len(lst))
return inner f = fun()
f(1)
f(2)
f(3)
f(4)
但是如果是不可变对象,比如integer和str等就不可以了。python3引入nonlocal后,灵活多了。尤其是在闭包和装饰器中,使用非常灵活和方便。那么接下来的博客我将展开讲解闭包和装饰器。
好了,最后 思考题,通过这个题目,好好体会一下global和nonlocal的神奇。
x=10
def fun(a):
global x
x = 2
def inner(y):
# global x
nonlocal a
a=a + 10
x=a + y
print(x)
return inner f = fun(10)
f(1)
print(x)
此时,inner函数内部,注释掉一句后,输出结果是:
21
2
但是当你把注释拿掉,结果是:
21
21
这就是global的神奇之处,它对一层函数有效,在内部的函数,如果你不加global,x=a+y时x就是一个函数内的局部变量。那么如果函数嵌套有几层,内层是不是还需要再加一层global呢,试试吧?
一文看懂global, nonlocal, local变量的更多相关文章
- 【转帖】一文看懂docker容器技术架构及其中的各个模块
一文看懂docker容器技术架构及其中的各个模块 原创 波波说运维 2019-09-29 00:01:00 https://www.toutiao.com/a6740234030798602763/ ...
- 一文看懂Java序列化
一文看懂Java序列化 简介 Java实现 Serializable 最基本情况 类的成员为引用 同一对象多次序列化 子父类引用序列化 可自定义的可序列化 Externalizable:强制自定义序列 ...
- 一文看懂web服务器、应用服务器、web容器、反向代理服务器区别与联系
我们知道,不同肤色的人外貌差别很大,而双胞胎的辨识很难.有意思的是Web服务器/Web容器/Web应用程序服务器/反向代理有点像四胞胎,在网络上经常一起出现.本文将带读者对这四个相似概念如何区分. 1 ...
- 一文看懂https如何保证数据传输的安全性的【转载、收藏】
一文看懂https如何保证数据传输的安全性的 一文看懂https如何保证数据传输的安全性的 大家都知道,在客户端与服务器数据传输的过程中,http协议的传输是不安全的,也就是一般情况下http是明 ...
- [转帖]一文看懂web服务器、应用服务器、web容器、反向代理服务器区别与联系
一文看懂web服务器.应用服务器.web容器.反向代理服务器区别与联系 https://www.cnblogs.com/vipyoumay/p/7455431.html 我们知道,不同肤色的人外貌差别 ...
- [转帖] 一文看懂:"边缘计算"究竟是什么?为何潜力无限?
一文看懂:"边缘计算"究竟是什么?为何潜力无限? 转载cnbeta 云计算 雾计算 边缘计算... 知名创投调研机构CB Insights撰文详述了边缘计算的发展和应用前景 ...
- 一文看懂Stacking!(含Python代码)
一文看懂Stacking!(含Python代码) https://mp.weixin.qq.com/s/faQNTGgBZdZyyZscdhjwUQ
- Nature 为引,一文看懂个体化肿瘤疫苗前世今生
进入2017年,当红辣子鸡PD-1疗法,一路横扫多个适应症.而CAR-T治疗的“小车”在获得FDA专委会推荐后也已经走上高速路,成为免疫治疗又一里程碑事件.PD-1.CAR-T之后,下一个免疫治疗产品 ...
- 一文看懂大数据的技术生态圈,Hadoop,hive,spark都有了
一文看懂大数据的技术生态圈,Hadoop,hive,spark都有了 转载: 大数据本身是个很宽泛的概念,Hadoop生态圈(或者泛生态圈)基本上都是为了处理超过单机尺度的数据处理而诞生的.你可以把它 ...
- 转载来自朱小厮博客的 一文看懂Kafka消息格式的演变
转载来自朱小厮博客的 一文看懂Kafka消息格式的演变 ✎摘要 对于一个成熟的消息中间件而言,消息格式不仅关系到功能维度的扩展,还牵涉到性能维度的优化.随着Kafka的迅猛发展,其消息格式也在 ...
随机推荐
- web259(超详细)
SoapClient看完之后还不是很懂的话就可以去下面的两个网址去补充一下 SoapClient 是 PHP 中用于与 SOAP(Simple Object Access Protocol)服务进行通 ...
- oeasy教您玩转vim - 50 - # 命令行效率
命令行效率 回忆上节课内容 总结 我们上次研究的是范围命令执行方法 批量控制缩进 :20,40> 批量执行普通模式下的命令 :4,10normal A; 直接切换到全屏命令模式 ex-mod ...
- Mac下浏览器跨域配置方法
open -n /Applications/Google\ Chrome.app/ --args --disable-web-security --user-data-dir=/Users/hooli ...
- Flink 架构学习总结
Flink是一个分布式系统,要求有效地分配和管理计算资源以执行流式应用程序.它集成了所有常见的集群资源管理器,如Hadoop YARN和Kubernetes,但也可以设置为作为standalone甚至 ...
- Python 基于win32com客户端实现Excel操作
测试环境 Python 3.6.2 代码实现 非多线程场景下使用 新建并保存EXCEL import win32com.client from win32api import RGB def save ...
- Python pluggy框架基础用法总结
代码为例进行说明 实践环境 Python 3.6.5 pluggy 0.13.0 例1 注册类函数为插件函数 #!/usr/bin/env python # -*- coding:utf-8 -*- ...
- 2023/4/19 SCRUM个人博客
1.我昨天的任务 初步了解了pandas库,对series和dataframe有了初步的学习使用 2.遇到了什么困难 对PYQT5的概念没有定义,准备进行学习 3.我今天的任务 学习了PYQT5的部分 ...
- scratch源码下载 | 几何冲刺
程序说明: <几何冲刺>是一款基于Scratch平台开发的跑酷类游戏程序.在这个游戏中,玩家控制一个黄色的小方块,在快速向前冲刺的过程中躲避各种障碍物.通过按下键盘上的上方向键,玩家可以操 ...
- Windows报错0xc0000142的处理方法
1.问题描述 桌面有个弹窗报错(0xc0000142),无法关闭,影响Windows的使用 此错误很有可能是缺少组件导致 2.解决办法 进入" C:\Windows\System32 &qu ...
- 【Java-GUI】02 Dialog对话框
--1.对话框 Dialog java.awt.Dialog 和Window一样可以独立存在的一个窗体 但是注意: 1.Dialog对象一定需要一个依附的父级窗口 2.两种模式(模式和非模式),模式打 ...