Python很多方面已经满足我们工作要求,那么他有什么不为人知的坑

本篇有点长,良心总结,希望大家可以少踩一点坑!

对于一些新手来说,使用python经常会遇到一些坑,如果不注重细节的话是不行的,下面就简单列举一些python中的坑:

一、列表创建和引用

1、嵌套列表的创建

使用*号来创建一个嵌套的list:

通过这个方法,可以得到一个包含3个list的嵌套list,我们来给第一个list增加一个元素:

嗨喽:正在学习python的小伙伴或者打算学习的,可以私信小编“01”领取资料!

通过输出的结果可以看初,我们只给第一元素增加元素,结果三个list都增加了一个元素。这是因为[[]]*3并不是创建了三个不同list,而是创建了三个指向同一个list的对象,所以,当我们操作第一个元素时,其他两个元素内容也会发生变化的原因。效果等同于下面这段代码:

我们可以打印出元素的内存地址一探究竟:

到这我们可以明白原因了。那如何解决了?可以这样:

这样我们就创建了三个不同的list对象

2、列表元素的引用

不要使用索引方法遍历list,例如:

比较好的方法是:

for语句会自动生成一个迭代器。如果你需要索引位置和元素,使用enumerate函数:

嗨喽:正在学习python的小伙伴或者打算学习的,可以私信小编“01”领取资料!

二、类变量初始化

不要在对象的init函数之外初始化类属性,主要有两个问题

  • 如果类属性更改,则初始值更改。
  • 如果将可变对象设置为默认值,您将获得跨实例共享的相同对象。

错误示范(除非你想要静态变量)

正确的做法:

Python很多方面已经满足我们工作要求,那么他有什么不为人知的坑

该代码的行为与预期的一样,但如果我们不传递参数呢?

这是因为函数参数类型是定义是确认的而不是运行时,所以在两次函数调用时,li指向的是同一个list对象,如果要解决这个问题,可以这样:

Python很多方面已经满足我们工作要求,那么他有什么不为人知的坑

这虽然解决了上述的问题,但,其他的一些对象,比如零长度的字符串,输出的结果就不是我们想要的。

Python很多方面已经满足我们工作要求,那么他有什么不为人知的坑

最常用的办法是检查参数是不是None

Python很多方面已经满足我们工作要求,那么他有什么不为人知的坑

for语句在遍历对象是会生成一个迭代器,如果你在遍历的过程中修改对象,会产生意想不到的结果:

alist = [0, 1, 2]

for index, value in enumerate(alist):

alist.pop(index)
print(alist)
# Out: [1]

第二个元素没有被删除,因为迭代按顺序遍历索引。上述循环遍历两次,结果如下:

Python很多方面已经满足我们工作要求,那么他有什么不为人知的坑

如果避免这个问题了,可以创建另外一个list

嗨喽:正在学习python的小伙伴或者打算学习的,可以私信小编“01”领取资料!

三、整数和字符串定义

python预先缓存了一个区间的整数用来减少内存的操作,但也正是如此,有时候会出很奇特的错误,例如:

另外一个例子

>>> (255 + 1) is (255 + 1)
True
>>> (256 + 1) is (256 + 1)
False

通过不断的测试,会发现(-3,256)这区间的整数都返回True,有的甚至是(-8,257)。默认情况下,[-5,256]会在解释器第一次启动时创建并缓存,所以才会有上面的奇怪的行为。这是个很常见但很容易被忽略的一个坑。解决方案是始终使用equality(==)运算符而不是 identity(is)运算符比较值。

Python还保留对常用字符串的引用,并且可以在比较is字符串的身份(即使用)时产生类似的混淆行为。

>>> 'python' is 'py' + 'thon'
True

python字符串被缓存了,所有python字符串都是该对象的引用,对于不常见的字符串,即使字符串相等,比较身份也会失败。

>>> 'this is not a common string' is 'this is not' + ' a common string'
False

>>> 'this is not a common string' == 'this is not' + ' a common string'
True

所以,就像整数规则一样,总是使用equal(==)运算符而不是 identity(is)运算符比较字符串值。

四、列表推导和循环中的变量泄漏

有个例子:

i = 0
a = [i for i in range(3)]
print(i) # Outputs 2

python2中列表推导改变了i变量的值,而python3修复了这个问题:

i = 0
a = [i for i in range(3)]
print(i) # Outputs 0

类似地,for循环对于它们的迭代变量没有私有的作用域

这种行为发生在Python 2和Python 3中。

为了避免泄漏变量的问题,请在列表推导和for循环中使用新的变量。

最后多说一句,小编是一名python开发工程师,这里有我自己整理了一套最新的python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。想要这些资料的可以关注小编,并在后台私信小编:“01”即可领取

相关推荐