​ Python作为一门简洁且容易上手的语言,正在受到越来越多人的喜爱。但如果你对其中的一些细节不甚了解,就有可能掉入它的“坑”里。本文将介绍学习Python过程中遇到的一些问题,接下来看看Python里一些常见的坑。

01

三元表达式

乍一看,按照根深蒂固的四则运算的思维,加号之前是一部分,加号之后为另一部分,结果貌似等于10。为什么打印出来的结果跟我们预想的大相径庭呢?很显然,Python解释器在遇到三元表达式时,默认把if之前的(10+4)作为三元表达式的前面部分了。

02

嵌套列表的创建

要创建一个嵌套的列表,我们可能会选择这样的方式:

目前看起来一切正常,我们得到了一个包含3个list的嵌套list。接下来往第一个list中添加一个元素:

奇怪的事情发生了,我们只想给第一元素增加元素,结果三个list都增加了一个元素。这是因为[[]]*3并不是创建了三个不同list,而是创建了三个指向同一个list的对象,所以,当我们操作第一个元素时,其他两个元素内容也会发生变化。下面的代码可以证实这一点:

正确的做法如下:

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, 10,10, 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=’a’的键值对神奇地消失了。这里不得不说一下Python字典是使用哈希表的思想实现的,Python 调用内部的散列函数,将键(Key)作为参数进行转换,得到一个唯一的地址,也就是哈希值。而Python 的哈希算法对相同的值计算得到的结果是一样的,这就很好地解释了上述情况出现的原因。

本文列出了在Python学习或者工作中可能会遇到的一些“坑”,虽然不见得每个人都能遇到上述问题,但是可以作为一个参考,以后就能避免踩坑了。希望小伙伴在跟Python打交道的过程中能多注意细节,甚至去了解一些内部实现的原理,这样才能更好地掌握Python这门语言。

python 获取第一个key_Python中常见的9大坑,看看你有没有遇到相关推荐

  1. Python之pandas:pandas中常见的数据类型转换四大方法以及遇到的一些坑之详细攻略

    Python之pandas:pandas中常见的数据类型转换四大方法以及遇到的一些坑之详细攻略 目录 pandas中常见的数据类型转换方法 T1.读取时直接转换数据类型 T2.采用astype

  2. python获取小图在大图中的坐标和相似度

    python获取小图在大图中的坐标和相似度 模块安装:pip install aircv 大小两个图片:big.jpg,small.jpg 模块安装:pip install aircv 大小两个图片: ...

  3. python配什么数据库_python中常见数据库有哪些

    python中常见的数据库有哪些呢?数据库大致分为两大类,第一类是包括关系数据库,第二类是非关系数据库,下面介绍一下这两类数据库的相关知识. 包括关系数据库:sqlite,mysql,mssql 非关 ...

  4. python和php互动_PHP中常见的五种设计模式

    您可能感兴趣的文章: 设计模式只是为 Java架构师准备的 - 至少您可能一直这样认为.实际上,设计模式对于每个人都非常有用.如果这些工具不是 "架构太空人" 的专利,那么它们又是 ...

  5. python获取字典长度_Python中的字典

    1 字典的定义 dictionary(字典) 是 除列表以外Python之中 最灵活的数据类型 字典同样可以用来 存储多个数据 通常用于存储 描述一个 物体的相关信息 和列表的区别 列表是 有序的对象 ...

  6. python有什么颜色_Python中常见颜色记录

    python中常见绘图的颜色选择 常见颜色 可选的颜色库 颜色名称对应的颜色码 names = { 'aliceblue': '#F0F8FF', 'antiquewhite': '#FAEBD7', ...

  7. 【Python】对一个字符串中的所有英文字母进行排序

    题目 对一个字符串中的所有英文字母进行排序 栗子 字符串 a = 'hello word' 排序后结果: ['d', 'e', 'h', 'l', 'l', 'o', 'o', 'r', 'w'] c ...

  8. python 映射表结构_Python 中常见的数据结构:字典、映射和散列表

    在 Python 中,字典是核心数据结构.字典可以存储任意数量的对象,每个对象都由唯一的字典键标识. 字典通常也被称为映射.散列表.查找表或关联数组.字典能够高效查找.插入和删除任何与给定键关联的对象 ...

  9. python在另一个函数中使用其他函数的变量_在另一个函数中访问函数的变量,如function() . var in python...

    我在寻找一种正确的方法来访问另一个函数中的函数变量时遇到了一些问题 . 我正在制作远程操作类工具,因此我需要处理接收的命令[如'exit'或'nircmdc.exe'或'telnet'等] . 下面的 ...

最新文章

  1. MINA2-TCP服务端实例
  2. optee应用程序中malloc函数的原理介绍
  3. java一键保存表格增删改,一个增删改功能的表格小demo
  4. java 图片分割_Java atlas图集分割
  5. 两台服务器虚拟成一个ip地址,两台服务器如何用一个ip地址
  6. 写一个http服务器
  7. 从LeetCode 210. Course Schedule II 了解拓扑排序
  8. 一位00后前端2年经验的成长历程
  9. 《数字逻辑设计与计算机组成》一 第2章 2.1 简介
  10. 弱网环境搭建方案选型
  11. python print(chr(65))_python 内置函数
  12. 【逆向】【PE入门】使用PEView分析PE文件
  13. Mybatis注解实现DAO层
  14. Flash Player去广告下载地址
  15. 整型常量(基于百度及各处资料加上我的个人经验整理而成)
  16. 无法打开internet站点ie6,7
  17. 所谓成长,就是认知升级
  18. snakemake--我最喜欢的流程管理工具
  19. linux美元符号含义
  20. uni-app中如何引入uViewUI?

热门文章

  1. 使用 Vue + Flask 搭建单页应用
  2. 好程序员web前端技术之CSS3过渡
  3. iOS中去除 Warning警告
  4. kotlin 中 lambda 表达式的 return 行为
  5. [转]httpclient编码
  6. select标签中的选项分组
  7. PHP获取客户端、PHP获取服务器相关信息
  8. Mac的控制台命令行报错:command not found
  9. CNN基础知识(2)
  10. Spring JdbcTemplate查询实例