对Python中一些“坑”的总结及技巧
一.赋值即定义
1.运行以下代码会出现报错
#!/usr/bin/env python
#_*_conding:utf-8_*_
x = 100
def outer():
def inner():
x += 100 #其实这里等效于"x = x + 100",我们直到这是一个赋值语句,会优先计算右边的等式,即"x + 100".而在此时由于x变量赋值即定义,即此时的x和全局作用域的x并非同一个对象。
print(x)
return inner
foo = outer()
foo()
2.使用global关键字解决以上报错
#!/usr/bin/env python
#_*_conding:utf-8_*_
x = 100
def outer():
def inner():
global x
#Python学习交流QQ群:579817333
#注意,我们先要在inner作用域中使用全局作用域的同名x变量就得优先使用"global"关键字进行声明。
x += 100
print(x)
return inner
foo = outer()
foo()
#以上代码输出结果如下:
200
3.不推荐使用global
global总结
x+=1这种是特殊形式产生的错误的原因?先引用后赋值,而python动态语言是赋值才算定义,才能被引用。解决办法,在这条语句前增加x=0之类的赋值语句,或者使用global告诉内部作用域,去全局作用域查找变量定义
内部作用域使用x = 5之类的赋值语句会重新定义局部作用域使用的变量x,但是,一旦这个作用域中使用global声明x为全局的,那么x=5相当于在为全局作用域的变量x赋值
global使用原则
外部作用域变量会内部作用域可见,但也不要在这个内部的局部作用域中直接使用,因为函数的目的就是为了封装,尽量与外界隔离
如果函数需要使用外部全局变量,请使用函数的形参传参解决
一句话:不用global。学习它就是为了深入理解变量作用域.
二.列表中的"+"与"+="的区别
1.观察以下代码
#!/usr/bin/env python
#_*_conding:utf-8_*_
def demo(x=[]):
x += [1] #就地修改前一个列表,在其后追加后一个列表。就是extend方法。
print(x)
print(demo.__defaults__) #我们可以查看默认参数列表
demo()
demo()
print(demo.__defaults__)
#发现demo函数被调用2次后,默认参数的值也在跟随着变化!其原因是demo()执行完后弹栈会消亡,但解释器始终保留了一份"def demo(x=[])"的函数签名,这里面的x变量会随着解释器的消亡而消亡,除非我们使用"del"关键字去现实的删除该函数!如果我们这样干的话,后续就无法访问到该函数啦!
#以上代码输出结果如下:
([],)
[1]
[1, 1]
([1, 1],)#!/usr/bin/env python
#_*_conding:utf-8_*_
def demo(x=[]):
x += [1] #就地修改前一个列表,在其后追加后一个列表。就是extend方法。
print(x)
#Python学习交流QQ群:579817333
print(demo.__defaults__) #我们可以查看默认参数列表
demo()
demo()
print(demo.__defaults__) #发现demo函数被调用2次后,默认参数的值也在跟随着变化!其原因是demo()执行完后弹栈会消亡,但解释器始终保留了一份"def demo(x=[])"的函数签名,这里面的x变量会随着解释器的消亡而消亡,除非我们使用"del"关键字去现实的删除该函数!如果我们这样干的话,后续就无法访问到该函数啦!
#以上代码输出结果如下:
([],)
[1]
[1, 1]
([1, 1],)
2.列表防坑总结
列表的"+"和"+="的区别:
"+"表示两个列表合并并返回一个全新的列表。
"+="表示,就地修改前一个列表,在其后追加一个列表。就是extend方法。
3.注意引用变量的是可以被就地修改的(以函数的默认值参数为例)
#!/usr/bin/env python
#_*_conding:utf-8_*_
def demo2(x=1,y="abc",z={},*args,m=100,n,**kwargs):
print(x,y,z) #打印位置参数
print(m,n) #打印key-only关键词参数
print(z.setdefault("abc","mn")) #我们为"z"变量设置一组键值对
print(demo2.__defaults__,demo2.__kwdefaults__)
#我们知道"__defaults__"保留的是位置参数相关信息,而"__kwdefaults__"保留的是关键字相关信息
demo2(n=200)
demo2(z = {},n = 200)
print(demo2.__defaults__,demo2.__kwdefaults__) #我们发现默认的"z"变量值是被咱们有意修改啦~
#以上代码输出结果如下:
(1, 'abc', {}) {'m': 100}
1 abc {}
100 200
mn
1 abc {}
100 200
mn
(1, 'abc', {'abc': 'mn'}) {'m': 100}

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
2019年Java面试题基础系列228道(2),查漏补缺!
2019年Java面试题基础系列228道 上一篇更新1~20题的答案解析https://yq.aliyun.com/articles/738108?spm=a2c4e.11155435.0.0.56793312VUpLTJ 本次更新Java 面试题(一)的21~50题答案 21、描述一下 JVM 加载 class 文件的原理机制? JVM 中类的装载是由类加载器(ClassLoader)和它的子类来实现的,Java 中的类加载器是一个重要的 Java 运行时系统组件,它负责在运行时查找和装入类文件中的类。 由于 Java 的跨平台性,经过编译的 Java 源程序并不是一个可执行程序,而是一个或多个类文件。当 Java 程序需要使用某个类时,JVM 会确保这个类已经被加载、连接(验证、准备和解析)和初始化。类的加载是指把类的.class 文件中的数据读入到内存中,通常是创建一个字节数组读入.class 文件,然后产生与所加载类对应的 Class 对象。加载完成后,Class 对象还不完整,所以此时的类还不可用。当类被加载后就进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默...
-
下一篇
Python 周刊第 418 期
新闻 PyCon US 2020 开始接受财务赞助! https://pycon.blogspot.com/2019/10/financial-aid-launches-for-pycon-us-2020.html2020年 Python 美国开发者大会,tips: 中国也有,可以赞助国内的) 已开放财务赞助申请,Pycon 将在 2020 年 1 月 31 日之前接受财务赞助。Python 软件基金会和 PyLadies 会对该大会进行财务赞助。今年,Python 软件基金会将提供 130000 美元的财务赞助,而 PyLadies 会根据 2019 年全年的捐款情况尽其所能赞助 Pycon。 VS Code 支持 Jupyter Notebook 的编辑 https://devblogs.microsoft.com/python/announcing-support-for-native-editing-of-jupyter-notebooks-in-vs-code/ 文章、教程或研讨会 用 Python 从 Last.fm API 接口获取音乐数据 https://www.dat...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL数据库在高并发下的优化方案
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2整合Thymeleaf,官方推荐html解决方案