对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并非同一个对象。

一.赋值即定义

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}
相关文章
|
算法 Python
【蓝桥杯考前一天总结PYthon终结篇】
【蓝桥杯考前一天总结PYthon终结篇】
195 0
【蓝桥杯考前一天总结PYthon终结篇】
|
存储 算法 Python
Python蓝桥杯易错点整理和心得总结【一】
Python蓝桥杯易错点整理和心得总结【一】
313 0
Python蓝桥杯易错点整理和心得总结【一】
|
算法 Python 容器
【蓝桥杯真题】18天Python组冲刺 心得总结
【蓝桥杯真题】18天Python组冲刺 心得总结
181 0
【蓝桥杯真题】18天Python组冲刺 心得总结
|
存储 数据可视化 Unix
Python中的时间序列数据操作总结
在本文中,我们介绍时间序列数据的索引和切片、重新采样和滚动窗口计算以及其他有用的常见操作,这些都是使用Pandas操作时间序列数据的关键技术。
187 0
Python中的时间序列数据操作总结
|
机器学习/深度学习 Python
进行图像增广(数据扩充)的15种功能总结和Python代码实现(三)
进行图像增广(数据扩充)的15种功能总结和Python代码实现
449 0
进行图像增广(数据扩充)的15种功能总结和Python代码实现(三)
|
Python
进行图像增广(数据扩充)的15种功能总结和Python代码实现(二)
进行图像增广(数据扩充)的15种功能总结和Python代码实现
326 0
进行图像增广(数据扩充)的15种功能总结和Python代码实现(二)
|
PyTorch 算法框架/工具 Python
进行图像增广(数据扩充)的15种功能总结和Python代码实现(一)
进行图像增广(数据扩充)的15种功能总结和Python代码实现
881 0
进行图像增广(数据扩充)的15种功能总结和Python代码实现(一)
|
XML JSON 自然语言处理
python接口自动化(三十三)-python自动发邮件总结及实例说明番外篇——下(详解)
发邮件前我们需要了解的是邮件是怎么一个形式去发送到对方手上的,通俗点来说就是你写好一封信,然后装进信封,写上地址,贴上邮票,然后就近找个邮局,把信仍进去,其他的就不关心了,只是关心时间,而电子邮件不像日常发送邮件的按天算,时间都是按秒算的。
211 0
python接口自动化(三十三)-python自动发邮件总结及实例说明番外篇——下(详解)
|
Java 数据库 索引
Python数据类型及其用法-总结篇
Python列表、元组、字典、集合、字符串用法对比总结
Python数据类型及其用法-总结篇