python学习之【第九篇】:Python中的变量作用域
1.前言
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
2.变量作用域
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:
- L (Local) 局部作用域
- E (Enclosing) 闭包函数外的函数中
- G (Global) 全局作用域
- B (Built-in) 内建作用域
以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。
Python中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,
- 局部作用域
x = int(3.3)
x = 0
def outer():
x = 1
def inner():
x = 2
print(x)
inner()
outer()
输出结果为2,因为此时直接在函数
inner内部找到了变量x。
- 闭包函数外的函数中
x = int(3.3)
x = 0
def outer():
x = 1
def inner():
i = 2
print(x)
inner()
outer()
输出结果为1,因为在内部函数
inner中找不到变量x,继续去局部外的局部——函数outer中找,这时找到了,输出 1。
- 全局作用域
x = int(3.3)
x = 0
def outer():
o = 1
def inner():
i = 2
print(x)
inner()
outer()
输出结果为0,在局部(
inner函数)、局部的局部(outer函数)都没找到变量x,于是访问全局变量,此时找到了并输出。
- 内建作用域
x = int(3.3)
g = 0
def outer():
o = 1
def inner():
i = 2
print(x)
inner()
outer()
执行结果为3,在局部(
inner函数)、局部的局部(outer函数)以及全局变量中都没有找到变量x,于是访问内建变量,此时找到了并输出。
3.全局变量与局部变量
变量有全局变量和局部变量之分。定义在函数内部的变量拥有局部作用域,称为局部变量;定义在函数外的变量拥有全局作用域,称为全局变量。局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。全局变量除非被手动删除,否则它们会存活到整个脚本运行结束,且对于脚本内所有的函数,全局变量的值都可以被访问。然而,局部变量仅仅依赖于定义它们的函数现阶段是否被调用,当函数被调用,则函数内部定义的局部变量就进入了声明它们的作用域,一旦函数运行完成,局部变量就会离开作用域,被释放掉。
g_str = "foo"
def foo():
l_str = "bar"
print(g_str) # 在局部作用域中访问全局变量,输出"foo"
print(l_str) # 在局部作用域中访问局部变量,输出"bar"
foo()
print(g_str) # 在全局作用域中访问全局变量,输出"foo"
print(l_str) # 在全局作用域中访问局部变量,报错
在上面例子中,变量g_str处于脚本的全局作用域中,为全局变量,所以在任意地方都可以被访问到;而l_str存在于foo()函数内,为局部变量,所以只能在函数内部被访问,函数外部的全局作用域中不能访问。
4.global关键字
在函数内部,可以任意访问全局作用域中的变量,但是不能修改,如果需要在函数内部修改全局作用域中的变量时,就必须使用global关键字。
- 对于不可变类型的全局变量来说,因其指向的数据不能修改,所以在改变时必须使用
global进行声明,否则会出错
a = 100
def test():
global a
print('-----修改前-----a=%s' % a)
a = 200
print('-----修改后-----a=%s' % a)
test()
# 输出
# -----修改前-----a=100
# -----修改后-----a=200
- 对于可变类型的全局变量来说,因其指向的数据可以修改,所以不使用global时也可修改全局变量。
li = [1, 2, 3]
def test1():
li.append(4)
print(li)
test1() # 输出[1,2,3,4]
5.nonlocal关键字
global关键字是直接修改全局变量时所需要声明的如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要nonlocal关键字了.
a = 100
def foo():
b = 200
def bar():
nonlocal b
print('-----修改前-----b=%s' % b)
b = 666
print('-----修改后-----b=%s' % b)
bar()
foo()
# 输出
# -----修改前-----b=200
# -----修改后-----b=666
上面例子中,在bar()函数内部修改上一级作用域中的变量b时,需要使用nonlocal进行声明。
(完)
python学习之【第九篇】:Python中的变量作用域的更多相关文章
- Python学习【第九篇】函数
函数 函数是什么? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上而下实现功能,其往往用一段代码来实现指定功能,开发过 ...
- JavaScript学习系列2一JavaScript中的变量作用域
在写这篇文章之前,再次提醒一下 JavaScript 是大小写敏感的语言 // 'test', 'Test', 'TeSt' , 'TEST' 是4个不同的变量名 JavaScript中的变量,最重要 ...
- Python学习第六篇——字典中的键和值
favorite_language ={ "jen":"python", "sarah":"c", "edwa ...
- python学习【第九篇】python面向对象编程
一.面向对象了解 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. Pyth ...
- Python之路(第九篇)Python文件操作
一.文件的操作 文件句柄 = open('文件路径+文件名', '模式') 例子 f = open("test.txt","r",encoding = “utf ...
- Python 学习 第十篇 CMDB用户权限管理
Python 学习 第十篇 CMDB用户权限管理 2016-10-10 16:29:17 标签: python 版权声明:原创作品,谢绝转载!否则将追究法律责任. 不管是什么系统,用户权限都是至关重要 ...
- Python学习笔记进阶篇——总览
Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(Socket编程进阶&多线程.多进程) Python学习笔记——进阶篇[第八周]———进程.线程.协程篇(异常处理) Pyth ...
- Python学习笔记基础篇——总览
Python初识与简介[开篇] Python学习笔记——基础篇[第一周]——变量与赋值.用户交互.条件判断.循环控制.数据类型.文本操作 Python学习笔记——基础篇[第二周]——解释器.字符串.列 ...
- python学习第八讲,python中的数据类型,列表,元祖,字典,之字典使用与介绍
目录 python学习第八讲,python中的数据类型,列表,元祖,字典,之字典使用与介绍.md 一丶字典 1.字典的定义 2.字典的使用. 3.字典的常用方法. python学习第八讲,python ...
- python学习第七讲,python中的数据类型,列表,元祖,字典,之元祖使用与介绍
目录 python学习第七讲,python中的数据类型,列表,元祖,字典,之元祖使用与介绍 一丶元祖 1.元祖简介 2.元祖变量的定义 3.元祖变量的常用操作. 4.元祖的遍历 5.元祖的应用场景 p ...
随机推荐
- 线程、进程概念与Android系统组件的关系
Android系统是Google公司基于Linux内核开发的开源手机操作系统.通过利用 Linux 内核的优势,Android 系统使用了大量操作系统服务,包括进程管理.内存管理.网络堆栈.驱动程序. ...
- Spring Boot 2.X(七):Spring Cache 使用
Spring Cache 简介 在 Spring 3.1 中引入了多 Cache 的支持,在 spring-context 包中定义了org.springframework.cache.Cache 和 ...
- 如何正确的在 Android 上使用协程 ?
前言 你还记得是哪一年的 Google IO 正式宣布 Kotlin 成为 Android 一级开发语言吗?是 Google IO 2017 .如今两年时间过去了,站在一名 Android 开发者的角 ...
- 《深入理解Java虚拟机》-----第13章 线程安全与锁优化
概述 在软件业发展的初期,程序编写都是以算法为核心的,程序员会把数据和过程分别作为独立的部分来考虑,数据代表问题空间中的客体,程序代码则用于处理这些数据,这种思维方式直接站在计算机的角度去抽象问题和解 ...
- 二、docker 镜像容器常用操作(让我们用docker 溜得飞起)
前言 上篇讲了我们如何安装docker,现在该我们一展拳脚的时候了.接下来让我们一起学习一下docker常见的操作,让我们能够会使用 docker. 基本概念 在讲使用之前,还是先将一下docker ...
- [BZOJ3029] 守卫者的挑战
Description 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜寻着关押applepi的监狱的所在地.突然,眼前一道亮光闪过.“我,Nizem,是黑魔法圣殿的守卫者.如果你能通过 ...
- css涂鸦这样玩
前言 上一次深扒CSS的时候,还说CSS和H5绘制复杂图形很麻烦,看了大神的操作后,感觉茅塞顿开了,哈哈. 就算可能我暂时没有用到的机会,学习一下开发者的设计思路也是受益匪浅呀. 嗯,今天要介绍的是一 ...
- g_pLog
g_pLog = new CLog("log"); g_pLog->Enable(); g_pScrLog = new CLog("data"); ...
- Vulnhub靶场渗透练习(三) bulldog
拿到靶场后先对ip进行扫描 获取ip 和端口 针对项目路径爆破 获取两个有用文件 http://192.168.18.144/dev/ dev,admin 更具dev 发现他们用到框架和语言 找到一 ...
- Spring Cloud ---- 服务消费与负载均衡(Rest + Ribbon )
上一篇主要写了基于Eurake的服务的注册,主要就是创建注册中心,创建服务者,将服务者注册到注册中心,完成服务的暴露.这一篇主要写服务的消费与服务消费的负载均衡. 服务的调用方式有两种,Rest + ...