nonlocal 与 global

nonlocal翻译是非本地,global翻译是全局,它们都是python3的新特性。如果以类C语言的思维去看这2个关键字,很可能觉得它们差不多。但实际上它们很不一样。

下面先说说global。顾名思义,global能将一个变量提升为全局, 但是这个关键字有个特别的语法要求,即不能同时定义和声明,如global a=1。

a = 1
def func():
print(a)
global a
a += 2 # SyntaxWarning: name 'a' is used prior to global declaration
func() #输出1
print(a) #输出3

不熟悉python的可能会举得上面的global有点多余,可能会倾向于下面这种写法:

a = 1
def func():
a += 2 func()
print(a)

可惜这么写只会报错UnboundLocalError: local variable 'a' referenced before assignment, 具体原因可以参考https://www.cnblogs.com/friedCoder/p/12571983.html

这种类C写法不能照搬到Python中,毕竟python是解释型语言,两者不可完全类比。

对于global再补充最后一个小点

def func():
global a
a = 1 print(a) #NameError: global name 'a' is not defined def func():
global a
a = 1 func()
print(a) #输出1

可以发现python竟然还能直接在函数里面定义外部的全局变量,当然没有global是做不到的,不过这种写法很不好。


下面再来看看nonlocal

既然已经有一个处理全局的关键字了,那nonlocal就是一个处理局部变量的关键字。

a = 1
def outer():
a = 2
def inner():
print(a)
nonlocal a
a = 3
inner()
print(a) outer()
print(a)

发现执行报错SyntaxError: name 'a' is used prior to nonlocal declaration, 因为函数inner里面a在声明nonlocal之前就被print调用了,这是不允许的, global一样。

a = 1
def outer():
a = 2
def inner():
nonlocal a
a = 3
inner()
print(a) #3 outer()
print(a) #1

可见nonlocal就是能引用外部环境的局部变量,遵守最近原则。

注意这里强调局部变量,下面都是不允许的:

a = 1
def outer():
def inner():
nonlocal a
a = 3
inner()
print(a) outer() #################################### def outer():
global a
def inner():
nonlocal a
a = 3
inner()
print(a) outer()

报错SyntaxError: no binding for nonlocal 'a' found

从上面可以看出python中修改外部变量挺麻烦的,因此最好使用面向对象的编程方法,而非面向过程。

python3中的nonlocal 与 global的更多相关文章

  1. 第九天python3 闭包、nonlocal、默认值的作用域

    闭包 自由变量:未在本地作用域中定义的变量,例如定义在内存函数外的外层函数的作用域中的变量: 闭包:出现在嵌套函数中,指的是内层函数引用到了外层函数的自由变量,就形成了闭包: 示例1: # -*- c ...

  2. Python3中变量作用域nonlocal的总结

    最近,在工作中踩到了一个关于Python3中nonlocal语句指定的变量作用域的坑.今天趁周六休息总结记录一下. 众所周知,Python中最常见的作用域定义如下:   但是,为了更加方便地在闭包函数 ...

  3. Python3中的新特性(1)——新的语言特性

    1.源代码编码和标识符         Python3假定源代码使用UTF-8编码.另外,关于标识符中哪些字符是合法的规则也放宽了.特别是,标识符可以包含代码点为U+0080及以上的任意有效Unico ...

  4. 函数的嵌套+nonlocal和global关键字(重点)

    1.在函数中声明函数 在内部函数中使用变量的时候, 查找顺序: 先找自己 -> 上一层 -> 上一层..全局 -> 内置 # 函数的互相调用 # def func1(): # pri ...

  5. 关于Python3中函数:

    # 关于Python3中函数: - 定义 定义函数使用关键字def,后接函数名和放在圆括号()中的可选参数列表,函数内容以冒号起始并且缩进.一般格式如下:``` def 函数名(参数列表): &quo ...

  6. Python3中的字符串函数学习总结

    这篇文章主要介绍了Python3中的字符串函数学习总结,本文讲解了格式化类方法.查找 & 替换类方法.拆分 & 组合类方法等内容,需要的朋友可以参考下. Sequence Types ...

  7. Python3中使用PyMySQL连接Mysql

    Python3中使用PyMySQL连接Mysql 在Python2中连接Mysql数据库用的是MySQLdb,在Python3中连接Mysql数据库用的是PyMySQL,因为MySQLdb不支持Pyt ...

  8. python3 中mlpy模块安装 出现 failed with error code 1的决绝办法(其他模块也可用本方法)

    在python3 中安装其它模块时经常出现 failed with error code 1等状况,使的安装无法进行.而解决这个问题又非常麻烦. 接下来以mlpy为例,介绍一种解决此类安装问题的办法. ...

  9. python3中返回字典的键

    我在看<父与子的编程之旅>的时候,有段代码是随机画100个矩形,矩形的大小,线条的粗细,颜色都是随机的,代码如下, import pygame,sys,random from pygame ...

随机推荐

  1. 5分钟使用NetModular 完成通讯录 App 开发

    原版连接:https://www.cnblogs.com/shanyou/p/12520894.html NetModular(后文简称NM)是 OLDLI 堪称艺术品级的应用开发框架,它基于经典领域 ...

  2. Java-用集合存储对象(新手)

    //导入的包.import java.util.ArrayList;//用集合存储对象,遍历集合,取所有元素. 用get方法.//创建的一个类.public class zylx4 { //公共静态的 ...

  3. router路由的使用

    router路由的使用 1.使用nuxt-link来跳转路由 <!-- 要跳转的路由的地址就是pages文件夹中定义的xxx.vue的前缀名--> <nuxt-link to=&qu ...

  4. go:数据类型

    Go语言中有丰富的数据类型,除了基本的整型.浮点型.布尔型.字符串外,还有数组.切片.结构体.函数.map.通道(channel)等.Go 语言的基本类型和其他语言大同小异. 1.基本数据类型 整型 ...

  5. Java - Java开发中的安全编码问题

    目录 1 - 输入校验 1.1 SQL 注入防范 1.2 XSS防范 1.3 代码注入/命令执行防范 1.4 日志伪造防范 1.5 XML 外部实体攻击 1.6 XML 注入防范 1.7 URL 重定 ...

  6. Data Management and Data Management Tools

    Data Management ObjectivesBy the end o this module, you should understand the fundamentals of data m ...

  7. 粒子群优化算法(PSO)之基于离散化的特征选择(FS)(二)

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 作者:Geppetto 前面我们介绍了特征选择(Feature S ...

  8. RMQ(倍增法求ST)

    解决什么问题:区间查询最值 倍增思想:每次得出结果的范围呈2的幂次增长,有人说相当于二分,目前我觉得相当于线段树的查找. 具体理解看代码: /*倍增法求ST*/ #include<math.h& ...

  9. 一夜搞懂 | JVM 类加载机制

    前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图 一.为什么要学习类加载机制? 今天想跟大家唠嗑唠嗑Java的类加载机制,这是Java的一个很重要的创 ...

  10. Swagger2 初始用

    1.结合Spring-Boot 引入 pom 依赖  <dependency> <groupId>io.springfox</groupId> <artifa ...