你知道Python中的4种变量作用域是哪些吗?
时间:2022-07-22
本文章向大家介绍你知道Python中的4种变量作用域是哪些吗?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
01 作用域
Python的作用域可以分为四种:
- L(Local) 局部作用域
- E(Enclosing) 闭包函数外的函数中
- G(Global) 全局作用域
- B(Built-in) 内建作用域
变量/函数 的查找顺序: L –> E –> G –>B
意思是,在局部找不到的,便去局部外的局部作用域找(例如 闭包),再找不到的就去全局作业域里找,再找不到就去内建作业域中找。
会影响 变量/函数 作用范围的有
- 函数:def 或 lambda
- 类:class
- 关键字:global noglobal
- 文件:*py
- 推导式:[],{},()等,仅限Py3.x中,Py2.x会出现变量泄露。
1、赋值在前,引用在后
# ------同作用域内------
name = "MING"
print(name)
# ------不同作用域内------
name = "MING"
def main():
print(name)
2、引用在前,赋值在后(同一作用域内)
print(name)
name = "MING"
# UnboundLocalError: local variable 'name' referenced before assignment
3、赋值在低层,引用在高层
# L -> E -> G -> B
# 从左到右,由低层到高层
def main():
name = "MING"
print(name)
# NameError: name 'name' is not defined
02 闭包
闭包这个概念很重要噢。你一定要掌握。
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。其实装饰函数,很多都是闭包。
好像并不难理解,为什么初学者会觉得闭包难以理解呢?
我解释一下,你就明白了。
一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
你可以看下面这段代码,就构成了闭包。在内函数里可以引用外函数的变量。
def deco():
name = "MING"
def wrapper():
print(name)
return wrapper
deco()()
# 输出:MING
03 改变作用域
变量的作用域,与其定义(或赋值)的位置有关,但不是绝对相关。
因为我们可以在某种程度上去改变向上
的作用范围。
- 关键字:global 将 局部变量 变为全局变量
- 关键字:nonlocal 可以在闭包函数中,引用并使用闭包外部函数的变量(非全局的噢)
global好理解,这里只讲下nonlocal。
先来看个例子
def deco():
age = 10
def wrapper():
age += 1
return wrapper
deco()()
运行一下,会报错。
# UnboundLocalError: local variable 'age' referenced before assignment
但是这样就OK
def deco():
age = 10
def wrapper():
nonlocal age
age += 1
return wrapper
deco()()
# 输出:11
其实,你如果不使用 +=
、-=
等一类的操作,不加nonlocal也没有关系。这就展示了闭包的特性。
def deco():
age = 10
def wrapper():
print(age)
return wrapper
deco()()
# 输出:10
04 变量集合
在Python中,有两个内建函数,你可能用不到,但是需要掌握它们。
- globals() :以dict的方式存储所有全局变量
- locals():以dict的方式存储所有局部变量
globals()
def foo():
print("I am a func")
def bar():
foo="I am a string"
foo_dup = globals().get("foo")
foo_dup()
bar()
# 输出
# I am a func
locals()
other = "test"
def foobar():
name = "MING"
gender = "male"
for key,value in locals().items():
print(key, "=", value)
foobar()
# 输出
# name = MING
# gender = male
- 再看最短路算法 1 —— 单源最短路
- 3402: [Usaco2009 Open]Hide and Seek 捉迷藏
- 1084: [SCOI2005]最大子矩阵
- 关于一般的并查集求根操作的一组对照研究
- vue计算属性详解——小白速会
- 【技巧】Java工程中的Debug信息分级输出接口及部署模式
- 1934: [Shoi2007]Vote 善意的投票
- 算法模板——线段树8 (字符串回文变换)
- 算法模板——哈希单模板字符串匹配
- javascript 原型及原型链详解
- 算法模板——并查集 2(支持快速即时查询本连通块内容,纯原创!)
- 1707: [Usaco2007 Nov]tanning分配防晒霜
- JavaScript 图片的上传前预览(兼容所有浏览器)
- 算法模板——sap网络最大流 3(递归+邻接表)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- R语言基于树的方法:决策树,随机森林,套袋Bagging,增强树
- R语言无监督学习:PCA主成分分析可视化
- 如何用r语言制作交互可视化报告图表
- R语言大数据分析纽约市的311万条投诉统计可视化与时间序列分析
- R语言动态可视化:制作历史全球平均温度的累积动态折线图动画gif视频图
- R语言里的非线性模型:多项式回归、局部样条、平滑样条、广义加性模型分析
- 使用R语言进行机制检测的隐马尔可夫模型HMM
- 【Kubernetes】Octant再探...
- 聊聊claudb的SlaveReplication
- 深度学习trick--labelsmooth
- Java锁的那些事儿
- React Hooks踩坑分享
- Python 自动化,Helium 凭什么取代 Selenium?
- Explain详解与索引最佳实践
- 使用SAP Analysis Path Framework (APF)展示CDS view数据