『无为则无心』Python函数 — 30、Python变量的作用域
1、作用于的概念
变量作用域指的是变量生效的范围,在Python中一共有两种作用域。
- 全局作用域
- 全局作用域在程序执行时创建,在程序执行结束时销毁。
- 所有函数以外的区域都是全局作用域。
- 在全局作用域中定义的变量,都属于全局变量,全局变量可以在程序的任意位置被访问。
- 函数作用域
- 函数作用域在函数调用时创建,在调用结束时销毁。
- 函数每调用一次就会产生一个新的函数作用域(不调用不产生)。
- 在函数作用域中定义的变量,都是局部变量,它只能在函数内部被访问。
2、局部变量
所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效。
def testA():
# 局部变量a
# 在函数中为变量赋值时,默认都是为局部变量赋值
# 局部变量不会影响函数外的变量。
a = 100
# 函数体内部访问,能访问到a变量
print(a)
testA() # 100
print(a) # 报错:name 'a' is not defined
变量
a
是定义在testA
函数内部的变量,在函数外部访问则立即报错。
局部变量的作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。
3、全局变量
所谓全局变量,指的是在函数体内、外都能生效的变量。
思考:如果有一个数据,在函数A
和函数B
中都要使用,该怎么办?
答:将这个数据存储在一个全局变量里面。
# 定义全局变量a
a = 100
def testA():
print(a) # 访问全局变量a,并打印变量a存储的数据
def testB():
print(a) # 访问全局变量a,并打印变量a存储的数据
testA() # 100
testB() # 100
思考:testB
函数需求修改变量a
的值为200,如何修改程序?
a = 100
def testA():
print(a)
def testB():
a = 200
print(a)
testA() # 100
testB() # 200
print(f'全局变量a = {a}') # 全局变量a = 100
思考:在testB
函数内部的a = 200
中的变量a
是在修改全局变量a
吗?
答:不是。观察上述代码发现,15行得到a
的数据是100,仍然是定义全局变量a
时候的值,而没有返回
testB
函数内部的200。综上:testB
函数内部的a = 200
是定义了一个局部变量。
(1)global关键字
思考:如何在函数体内部修改全局变量?
a = 100
def testA():
print(a)
def testB():
# 想要修改全局变量a的值是200
# global 关键字声明a是全局变量
global a
a = 200
print(a)
testA() # 100
testB() # 200
print(f'全局变量a = {a}') # 全局变量a = 200
global
关键字的作用是,在函数内部声明一个变量为全局变量。换句话说如果希望在函数内部修改全局变量,则需要使用global
关键字来声明变量。
(2)总结
- 如果在函数里面直接把变量a=200赋值,此时的
a
不是全局变量的修改,而是相当于在函数内部声明了一个新的局部变量。 - 函数体内部修改全局变量: 先
global
声明a
为全局变量,然后再变量重新赋值。
4、变量的查找
当我们使用变量时,会优先在当前作用域中寻找该变量,如果有则使用,
如果没有则继续去上一级作用域中寻找,如果有则使用,
如果依然没有则继续去上一级作用域中寻找,以此类推。
直到找到全局作用域,依然没有找到,则会抛出异常 NameError: name 'a' is not defined
。
# 练习说明
a = 10
def fn2():
def fn3():
a = 30
print('fn3中:','a =',a)
fn3()
print('fn2中:','a =',a)
fn2()
"""
输出结果:
fn3中: a = 30
fn2中: a = 10
"""
5、作用域中可变数据类型变量
c = 10
def fn4(a):
# 在函数中对形参进行重新赋值,不会影响其他的变量
a = 20
print('a =', a, id(a))
fn4(c)
print('c =', c, id(c))
"""
输出结果:
a = 20 8791349231264
c = 10 8791349230944
"""
# 如果形参接收到的数据是一个全局列表
# 当在函数内尝试修改列表中的元素时,全局列表的数据也会发生改变
c = [1,2,3]
def fn4(a):
# 如果形参执行的是一个对象,当我们通过形参去修改对象时
# 会影响到所有指向该对象的变量
a[0] = 100
print('a =', a, id(a))
fn4(c)
print('c =', c, id(c))
"""
输出结果:
a = [100, 2, 3] 5132808
c = [100, 2, 3] 5132808
"""
# 如果我们不向全局变量有所改动
# 就需要使用我们之前学过的浅复制,
# 或者传入一个切片,就可以解决
c = [1, 2, 3]
def fn4(a):
# 在函数中对形参进行重新赋值,不会影响其他的变量
a[0] = 100
print('a =', a, id(a))
fn4(c.copy())
# fn4(c[:])
print('c =', c, id(c))
"""
输出结果:
a = [100, 2, 3] 6050824
c = [1, 2, 3] 6050312
"""
6、多函数程序执行流程
一般在实际开发过程中,一个程序往往由多个函数组成,并且多个函数共享某些数据,如下所示:
(1)共用全局变量
# 1. 定义全局变量
glo_num = 0
def test1():
global glo_num
# 修改全局变量
glo_num = 100
def test2():
# 调用test1函数中修改后的全局变量
print(glo_num)
# 2. 调用test1函数,执行函数内部代码:声明和修改全局变量
test1()
# 3. 调用test2函数,执行函数内部代码:打印
test2() # 100
(2)返回值作为参数传递
# 先得到函数一的返回值,再把这个返回值传入到函数二
def test1():
return 50
def test2(num):
print(num)
# 1. 保存函数test1的返回值
result = test1()
# 2.将函数返回值所在变量作为参数传递到test2函数
test2(result) # 50
『无为则无心』Python函数 — 30、Python变量的作用域的更多相关文章
- 『无为则无心』Python函数 — 26、Python函数参数的传递方式
目录 1.位置参数 2.关键字参数 3.缺省参数(默认参数) 4.不定长参数(可变参数) (1)包裹位置传递 (2)包裹关键字传递 5.位置参数.默认参数.可变参数的混合使用 6.拓展:参数解包 提示 ...
- 『无为则无心』Python函数 — 27、Python函数的返回值
目录 1.返回值概念 2.return关键字的作用 3.返回值可以返回的数据类型 4.函数如何返回多个值 5.fn5 和 fn5()的区别 6.总结: 1.返回值概念 例如:我们去超市购物,比如买饮料 ...
- 『无为则无心』Python函数 — 29、Python变量和参数传递
目录 1.Python的变量 (1)Python变量不能独立存在 (2)变量是内存中数据的引用 (3)注意点 2.了解变量的引用 3.Python的参数传递(重点) (1)示例 (2)结论 (3)总结 ...
- 『无为则无心』Python函数 — 25、Python中的函数
目录 1.函数的使用 (1)定义函数 (2)调用函数 (3)使用函数的注意事项 2.函数的参数 3.实参的类型 Python函数的说明: Python中函数的应用非常广泛,前面章节中我们已经接触过多个 ...
- 『无为则无心』Python函数 — 28、Python函数的简单应用
目录 1.函数嵌套调用 2.Python函数的简单应用 (1)打印线条 (2)函数计算 (3)打印图形 3.函数的说明文档 (1)函数的说明文档的作用 (2)函数说明文档的语法 (3)查看函数的说明文 ...
- 『无为则无心』Python函数 — 31、命名空间(namespace)
目录 1.什么是命名空间 2.三种命名空间 3.命名空间查找顺序 4.命名空间的生命周期 5.如何获取当前的命名空间 1.什么是命名空间 命名空间指的是变量存储的位置,每一个变量都需要存储到指定的命名 ...
- 『无为则无心』Python函数 — 33、高阶函数
目录 1.高阶函数的定义 2.体验高阶函数 3.内置高阶函数 (1)map()函数 (2)reduce()函数 (3)filter()函数 1.高阶函数的定义 把函数作为参数传入(把一个函数作为另外一 ...
- 『无为则无心』Python序列 — 23、Python序列的公共API
目录 1.运算符 @1.+加号 @2.*乘号 @3.in或not in 2.公共方法 @1.len()方法 @2.del和del() @3.max()方法 @4.min()方法 @5.range() ...
- 『无为则无心』Python基础 — 4、Python代码常用调试工具
目录 1.Python的交互模式 2.IDLE工具使用说明 3.Sublime3工具的安装与配置 (1)Sublime3的安装 (2)Sublime3的配置 4.使用Sublime编写并调试Pytho ...
随机推荐
- java标识接口
标识接口是没有任何方法和属性的接口,标识接口不对实现类有任何语义上的要求,仅仅表明它的实现类属于一个特定的类型.它非常类似于Web 2.0中的TAG的概念,Java使用它标识某一类对象.主要有两个用途 ...
- Service Worker的应用
Service Worker的应用 Service worker本质上充当Web应用程序.浏览器与网络(可用时)之间的代理服务器,这个API旨在创建有效的离线体验,它会拦截网络请求并根据网络是否可用来 ...
- Apache Log4j2,RASP 防御优势及原理
Apache Log4j2 远程代码执行漏洞已爆发一周,安全厂商提供各类防御方案和检测工具,甲方团队连夜应急. 影响持续至今,网上流传的各种利用和绕过姿势还在层出不穷,影响面持续扩大.所有安全人都开始 ...
- 如何实现 range 函数的参数?
关于 range 函数 Python内置的range函数可以接收三个参数: class range(stop): ... class range(start, stop[, step]): ... 标 ...
- 数据脱敏 t-closeness介绍与实现
数据脱敏 t-closeness介绍与实现 本文主要基于t-closeness的首次提出团队Ninghui Li, Tiancheng Li, Suresh Venkatasubramanian发表的 ...
- C# 使用TimeSpan秒数转化为时分秒的写法
1.TimeSpan的生成方法 // 参数: // ticks: // A time period expressed in 100-nanosecond units. public TimeSpan ...
- 查找MySql的配置文件my.cnf所在路径
Linux系统 linux 上可以使用 mysql --help|grep my.cnf 过滤查看 [root@localhost etc]# mysql --help|grep my.cnf ord ...
- Go1.18中的泛型编程
目录 目录 前言 泛型是什么 Go的泛型 泛型函数 泛型类型 类型集合 和接口的差异 总结 前言 经过这几年的千呼万唤,简洁的Go语言终于在1.18版本迎来泛型编程.作为一门已经有了14年历史的强类型 ...
- CMAKE为项目输出名添加后缀
概述 本文将介绍cmake配置动态库和可执行程序两种,使用cmake为其添加Debug和Release配置下的后缀 动态库 下面将介绍使用CMAKE_DEBUG_POSTFIX和CMAKE_RELEA ...
- 『与善仁』Appium基础 — 30、操作微信小程序
目录 1.测试微信小程序前提 2.获取微信小程序的进程 3.代码示例 4.补充:(了解) 微信小程序和微信公众号的测试方式基本上是一样的. 微信的小程序越来越多了,随之带来的问题是:小程序如何做自动化 ...