【Python】Python中常见的9大坑,看看你有没有遇到!( 二 )
正确的做法如下:
03
try...finally + return
看下面这段代码 , 可以试想一下print语句打印的顺序:
是不是很多小伙伴看到return就对print的顺序感到不知所措了 , 下图是最终的结果:
我们先来看一段Python官网对于finally的解释:
翻译成中文就是try块中包含break、continue或者return语句的 , 在离开try块之前 , finally中的语句也会被执行 。 所以在上面的例子中 , try块return之前 , 会执行finally中的语句 , 最后再执行try中的return语句返回结果 。 看到这里小伙伴们都豁然开朗了吧 。
04
参数默认值
当我们把函数的参数默认值设置为列表时 , 会发生什么?
出现以上情况的原因是:默认值在定义函数时计算(通常在加载模块时) , 因此默认值变成了函数对象的属性 。 具体来说 , 函数的参数默认值保存在函数的__defaults__属性中 , 指向了同一个列表 。 因此 , 如果默认值是可变对象 , 而且修改了它的值 , 那么后续的函数调用都会受到影响 。 正确的做法是设置该参数默认为None 。
05
lambda自由参数之坑
先来看这样一段代码:
结果并不是0 , 2 , 4 , 6 , 8 , 而是8 , 8 , 8 , 8 , 8 。 不少人可能会觉得匪夷所思 , 不着急 , 先试着用dis库分析字节码 。
没有得到想要的结果 , 只能看到参数i和x , 参数i的具体值无法获取 。 这也就是说lambda函数在定义的时候只知道有一个i , 而他的值并不明确 , 之后通过计算获取i的值 。 到这里很容易联想到闭包 , 因为i引用了“for i in range(5)”这个表达式中的值 。 先复习一下“闭包”的定义:闭包是一种函数 , 它会保留定义函数时存在的自由变量的绑定 , 这样调用函数时 , 虽然定义作用域不可用了 , 但是仍能使用那些绑定 。 接下来验证一下 , 我们通过f.__code__.co_freevars来获取自由变量的名称 , 通过f.__closure__[0
.cell_contents得到自由变量的值:
果不其然 , 自由变量i最终的值都是4 , 这也就解释了最开始的结果 。 如果还不明白可以看下面这段代码 。
Python程序从上到下执行 , 同时它也是一门动态型的语言 , 举个例子 , 定义一个类之后 , 你可以动态的给它增加方法 。 同样 , 上面这个例子中 , 程序执行到最后i的值为5 , 所以lambda表达式中i为5 , 最终的结果为:[10 1010 10 10 10
。
要解决上述出现的问题 , 就要把闭包作用域变为局部作用域:
a = [lambda x i=i: i*x for i in range(5)
。 这行代码等效于下面这种写法:
“纸上得来终觉浅 , 绝知此事要躬行” 。
06
含单个元素的元组
上图有两行新建元组的代码 , 但只有第二种写法是正确的 。 因为在唯一的元素之后不加逗号 , 小括号对于Python解释器是无效的 。
07
对象销毁顺序
创建一个类OBJ:
创建两个OBJ示例 , 使用is判断是否为同一对象:
接下来同样创建两个对象 , 使用id来判断 。
调用id函数 Python 创建一个OBJ类的实例 , 并使用id函数获得内存地址后 , 销毁内存丢弃这个对象 。 当连续两次进行此操作 Python会将相同的内存地址分配给第二个对象 , 所以两个对象的id值是相同的 。 但是is行为却与之不同 , 通过打印顺序就可以看到 。
08
了解执行时机
请看下面这个例子:
结果并不是[1 3 5
而是[5
, 这有些不可思议 。 原因在于 , in子句在声明时执行 而条件子句则是在运行时执行 。 所以上图中的生成器等价于:
09
相同值的不可变对象
可以看到 , key=1 , value=https://mparticle.uc.cn/api/’a’的键值对神奇地消失了 。 这里不得不说一下Python字典是使用哈希表的思想实现的 , Python 调用内部的散列函数 , 将键(Key)作为参数进行转换 , 得到一个唯一的地址 , 也就是哈希值 。 而Python 的哈希算法对相同的值计算得到的结果是一样的 , 这就很好地解释了上述情况出现的原因 。
推荐阅读
- Python之王|Pandas数据合并与拼接的5种方法
- 产业气象站|学完python可以从事哪些行业?
- 毒蛇▲中国十大没有毒的蛇 国内最常见无毒蛇类
- ZAKER生活|电热水壶常见品牌有哪些
- 中国移动:中国移动这两个“古董号”号段你有吗?很珍贵,如今已不常见!
- 雷科技|9.9元100G,30元1万G流量!这些手机套餐全是大坑
- 知足常乐|如今已不常见,中国移动这两个“古董号”号段你有吗?很珍贵
- 泰安大掌柜财税服务|泰安大掌柜财税|商标注册时常见疑问:TM和R区别?个人和公司申请商标区别?
- 『算法』面试常见问题jvm的调优思路
- 中国统计网|一份【同时选择行列方法】的盘点送给你,Python拍了拍你