global

表示不再使用局部局部作用域中的内容,而是改用全局作用域中的变量

 a = 100

 def func():
global a # 表示不再局部创建这个变量,而是直接使用这个全局的a
a = 28
print(a) func()
print(a)

执行结果

28
28 Process finished with exit code 0

对于可变的数据类型如列表、字典等也可以使用global

 lst = [1, 2, 3]
dic = {1: 1, 2: 2} def func():
global lst
global dic
lst = [2, 3, 4]
dic = {1: 10, 2: 20}
print(lst)
print(dic) func()
print(lst)
print(dic)

执行结果

[2, 3, 4]
{1: 10, 2: 20}
[2, 3, 4]
{1: 10, 2: 20} Process finished with exit code 0

对于可变数据类型,如果不加global,那么可以追加元素,删除元素,修改元素,但是不能直接赋值(就是不能 lst =[....]),直接赋值的结果是创建一个局部的列表或字典

 lst = ["麻花疼", "刘强东", "雷军军"]
dic = {"马云": "淘宝"} def func():
lst.append("马云云")
# lst = ["马化腾", "雷军"]
lst.remove("刘强东")
dic["强东"] = "京东"
dic["马云"] = "支付宝"
print(lst)
print(dic) func()
print(lst)
print(dic)

执行结果

['麻花疼', '雷军军', '马云云']
{'马云': '支付宝', '强东': '京东'}
['麻花疼', '雷军军', '马云云']
{'马云': '支付宝', '强东': '京东'} Process finished with exit code 0

如果在函数里面直接赋值,结果会是怎么样的呢,来看代码

 lst = ["麻花疼", "刘强东", "雷军军"]
dic = {"马云": "淘宝"} def func():
# lst.append("马云云")
lst = ["马化腾", "雷军"] # 相当于在局部名称空间重新创建一个变量lst指向新列表[...]
# lst.remove("刘强东")
dic["强东"] = "京东" # 直接对全局名称空间的dic进行修改
# dic["马云"] = "支付宝"
print(lst)
print(dic) func()
print(lst)
print(dic)

执行结果

['马化腾', '雷军']
{'马云': '淘宝', '强东': '京东'}
['麻花疼', '刘强东', '雷军军']
{'马云': '淘宝', '强东': '京东'} Process finished with exit code 0

nonlocal

nonlocal表示在局部作用域内,调用父级命名空间中的变量

 a = 10

 def func1():
a = 20 # 局部变量 def func2():
# nonlocal a # 调用func1里面的a(值为20)
a = 30 # 将func1里面a的值改为30
print(a) # 打印30 func2()
print(a) # func1里面a的值已经改为30了,因此打印30,不加nonlocal打印20 func1()
print(a) # 打印全局变量a(值为10)

执行结果

30
30
10 Process finished with exit code 0

综合运用

来看一段代码

a = 1

def func1():
a = 2 def func2():
nonlocal a
a = 3 def func3():
a = 4
print(a)
print(a)
func3()
print(a)
print(a)
func2()
print(a) print(a)
func1()
print(a)

运行结果

1
2
3
4
3
3
1 Process finished with exit code 0

来看分析,注意执行顺序,从上往下,遇到函数定义跳过,遇到函数调用时跳转到函数定义,函数体执行完接着之前的位置执行。

a = 1      # 创建全局变量a(值为1)

def func1():
a = 2 # 创建局部变量a def func2():
nonlocal a # 调用func1(父级命名空间)里面的a
a = 3 # 把func1里面a的值改为3 def func3():
a = 4 # 创建局部变量a
print(a) # 打印func3里面局部变量a的值4-----4
print(a) # 打印func2里面的a的值3------3
func3()
print(a) # 打印func2里面的a的值3(func3里面的a不影响func2的a)------5
print(a) # 打印func1里的局部变量a的值2------2
func2()
print(a) # 打印func1里面的a的值3(func1里面的a已经被func2改成了3)-------6 print(a) # 打印全局变量a的值1------------1
func1() # 跳转到func1定义的位置
print(a) # 打印1---------7

总结

(1)调用变量是要搞清楚变量是全局变量还是局部变量,如果是局部变量的话是属于哪个函数的,它能否被其子函数调用

(2)注意代码的执行顺序,代码从上往下执行,遇到函数定义跳过,等到遇到函数调用时才跳转到定义的部分开始执行,执行完了后再跳转到函数调用的地方

函数的作用域、global与nonlocal的更多相关文章

  1. 动态参数(*args,**kwargs),命名空间和作用域,global和nonlocal,函数的嵌套

    1. 动态参数 位置参数的动态参数: *args 关键字参数的动态参数 : **kwargs 顺序: 位置,*args,默认值,**kwargs 在形参上*聚合, **聚合 在实参上*打散, **打散 ...

  2. 07.python函数作用域global、nonlocal、LEGB

    函数作用域 作用域 一个标识符的课件范围,这就是标识符的作用域,一般常说的是变量的作用域 def foo():    x = 100 print(x) # 可以访问到吗 上例中x不可以访问到,会抛出异 ...

  3. python(动态传参、命名空间、函数嵌套、global和nonlocal关键字)

    一.函数的动态传参 1.*args位置参数动态传参 def chi(*food): print(food) chi("烧烤","火锅","虾吃虾涮&q ...

  4. python 函数的动态参数 命名空间,作用域以及函数嵌套,global和nonlocal (重点)

    *** 坚持坚持,即使你不太强*** 1.函数的动态传参 2.函数的命名空间及作用域 3.函数嵌套 4.global和nonlocal关键字 一.函数的动态传参 1. *args: 位置参数动态传参, ...

  5. Python_动态参数、名称空间、作用域、作用域链、加载顺序、函数的嵌套、global、nonlocal

    1.动态参数 当实参数量与形参数量相等时,参数传递正常. def func1(a, b, c): pass func1(1, 2, 3) 当实参数量与形参数量不相等时,则会报错. def func1( ...

  6. Python之函数--命名空间、作用域、global、nonlocal、函数的嵌套和作用域链

    命名空间 -------‘’存放名字与值的关系”的空间 代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间: 在函数的运行中开辟的临时的空间叫做局部命名空间. 命名空间一共分为三种: ...

  7. 【学习笔记】--- 老男孩学Python,day10, 函数, 动态参数 命名空间\作用域 global nonlocal

    1. 动态参数 位置参数的动态参数: *args 关键字参数的动态参数 : **kwargs 顺序:位置---*args---默认值---**kwargs 在形参上*聚合, **聚合 在实参上*打散, ...

  8. 动态参数 名称空间 作用域 作用域链 加载顺序 函数的嵌套 global nonlocal 等的用法总结

    03,动态参数 *args,**kwargs # 用户传入到函数中的实参数量不定时,或者是为了以后拓展,# 此时要用到动态参数*args,**kwargs(万能参数.)# *args接收的是所有的位置 ...

  9. CSIC_716_20191111【函数对象、名称空间、作用域、global 和nonlocal】

    函数名是可以被引用,传递的是函数的内存地址.函数名赋值给变量后,只需要在变量后加上括号即可调用函数. 名称空间 内置名称空间:在python解释器中提前定义完的名字 全局名称空间:if.while.f ...

  10. python中global 和 nonlocal 的作用域

    python引用变量的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量 . 一 global global关键字用来在函数或其他局部作用域 ...

随机推荐

  1. 洛谷CF809C Find a car(数位DP)

    洛谷题目传送门 通过瞪眼法发现,\(a_{i,j}=(i-1)\text{ xor }(j-1)+1\). 二维差分一下,我们只要能求\(\sum\limits_{i=0}^x\sum\limits_ ...

  2. Codeforces Round #463 F. Escape Through Leaf (李超线段树合并)

    听说正解是啥 set启发式合并+维护凸包+二分 根本不会啊 , 只会 李超线段树合并 啦 ... 题意 给你一颗有 \(n\) 个点的树 , 每个节点有两个权值 \(a_i, b_i\) . 从 \( ...

  3. IDEA+Springboot+JRebel热部署实现

    步骤一:在IDEA中安装JRebel插件(File->settings->plugins->search in repositories),如下图 步骤二:安装完成之后,重启idea ...

  4. Java 类设计技巧

    摘自<Java核心技术>卷I:基础知识 p140 第4章对象与类 - 类设计技巧 1)一定将数据设计为私有. 最重要的是:绝对不要破坏封装性.有时候,需要编写一个访问器方法或更改器方法,但 ...

  5. Android 程序优化总结

    第一部分 编程规范 1.1 基本要求: 程序结构清晰,简单易懂,单个函数的程序行数不得超过100行. 打算干什么,要简单,直接. 尽量使用标准库函数和公共函数 不要随意定义全局变量,尽量使用局部变量. ...

  6. 【CF526G】Spiders Evil Plan(贪心)

    [CF526G]Spiders Evil Plan(贪心) 题面 洛谷 CodeForces 给定一棵树,要求选择\(y\)条链,满足被链覆盖的所有点在树上联通,且\(x\)必定在联通块中. 对于每次 ...

  7. Nginx log日志切割shell

    #!/bin/bash#此脚本用于自动分割Nginx的日志,包括access.log和error.log#每天00:00执行此脚本 将前一天的access.log重命名为access-xxxx-xx- ...

  8. 老铁,告别postman,用pycharm来调接口,顺便把接口脚本也写了

    最近,一位同事在用postman调涉及到依赖的接口的时候 postman设置了环境变量,但是老是获取不到依赖接口返回的值,至于的啥原因呢,@#¥%……&*()! 其实,用pycharm一样可以 ...

  9. 利用LVS+Keepalived搭建Mysql双主复制高可用负载均衡环境

    应用背景: MySQL复制(主主,主从...)能在保证数据的备份的同时也能够做读写分离分摊系统压力,但是发生单点故障时,需要手动 切换到另外一台主机.LVS和Keppalived可以设定一个VIP来实 ...

  10. linux复制文件到一个不存在的文件夹

    复制文件到一个不存在的文件夹时,会报错 cp -f aaa /home/admin/.m2/cp: 无法创建普通文件"/home/admin/.m2/": 是一个目录 解决的方式: ...