谈谈 Python 那些不为人知的冷知识(三)

第一时间关注Python技术干货!

冷知识系列,直至今日,已经更新至第三篇。

前两篇传送门小明给你准备好了,还没阅读的可以学习一下。

还是老规矩,一篇只分享五个,有时间了就整理。不想错过的,千万记得关注一下。希望大家有相关冷知识,可以向我投稿。有小红包奖励噢。

01

for 死循环

for 循环可以说是 基础得不能再基础的知识点了。但是如果让你用 for 写一个死循环,你会写吗?(问题来自群友 陈**)

这是个开放性的问题,在往下看之前,建议你先尝试自己思考,你会如何解答。

好了,如果你还没有思路,那就来看一下 一个海外 MIT 群友的回答:

foriiniter(int,1):pass

是不是懵逼了。iter 还有这种用法?这为啥是个死循环?

这真的是个冷知识,关于这个知识点,你如果看中文网站,可能找不到相关资料。

还好你可以通过 IDE 看py源码里的注释内容,介绍了很详细的使用方法。

原来iter有两种使用方法,通常我们的认知是第一种,将一个列表转化为一个迭代器。

而第二种方法,他接收一个 callable对象,和一个sentinel 参数。第一个对象会一直运行,直到它返回 sentinel 值才结束。

那呢,这又是一个知识点,int 是一个内建方法。通过看注释,可以看出它是有默认值0的。你可以在终端上输入看看是不是返回0。

由于int() 永远返回0,永远返回不了1,所以这个 for 循环会没有终点。一直运行下去。

这些问题和答案都源自于群友的智慧。如果你也想加入我们的讨论中,请到公众号后台,添加我个人微信,备注「加群」,你也我邀请你进入。

02

奇怪的字符串

示例一

示例二

>>> a ="MING"

>>> b ="MING"

>>> aisb

True

# Python2.7

>>> a, b ="MING!","MING!"

>>> aisb

True

# Python3.7

>>> a, b ="MING!","MING!"

>>> aisb

False

示例三

# Python2.7

>>>'a'*20is'aaaaaaaaaaaaaaaaaaaa'

True

>>>'a'*21is'aaaaaaaaaaaaaaaaaaaaa'

False

# Python3.7

>>>'a'*20is'aaaaaaaaaaaaaaaaaaaa'

True

>>>'a'*21is'aaaaaaaaaaaaaaaaaaaaa'

True

03

两次return

我们都知道,try…finally… 语句的用法,不管 try 里面是正常执行还是报异常,最终都能保证finally能够执行。

同时,我们又知道,一个函数里只要遇到 return 函数就会立马结束。

基于以上这两点,我们来看看这个例子,到底运行过程是怎么样的?

>>>deffunc():

...try:

...return'try'

...finally:

...return'finally'

...

>>> func()

'finally'

惊奇的发现,在里的return居然不起作用。

原因是,在try…finally…语句中,try中的return会被直接忽视,因为要保证finally能够执行。

04

小整数池

先看例子。

>>> a = -6

>>> b = -6

>>> a is b

False

>>> a =256

>>> b =256

>>> a is b

True

>>> a =257

>>> b =257

>>> a is b

False

>>> a =257; b =257

>>> a is b

True

为避免整数频繁申请和销毁内存空间,Python 定义了一个小整数池[-5, 256] 这些整数对象是提前建立好的,不会被垃圾回收。

以上代码请在 终端Python环境下测试,如果你是在IDE中测试,并不是这样的效果。

那最后一个示例,为啥又是True?

因为当你在同一行里,同时给两个变量赋同一值时,解释器知道这个对象已经生成,那么它就会引用到同一个对象。如果分成两成的话,解释器并不知道这个对象已经存在了,就会重新申请内存存放这个对象。

05

intern机制

字符串类型作为 Python 中最常用的数据类型之一,Python解释器为了提高字符串使用的效率和使用性能,做了很多优化。

例如:Python 解释器中使用了 intern(字符串驻留)的技术来提高字符串效率。

什么是 intern 机制?就是同样的字符串对象仅仅会保存一份,放在一个字符串储蓄池中,是共用的,当然,肯定不能改变,这也决定了字符串必须是不可变对象。

>>> s1="hello"

>>> s2="hello"

>>> s1iss2

True

# 如果有空格,默认不启用intern机制

>>> s1="hell o"

>>> s2="hell o"

>>> s1iss2

False

# 如果一个字符串长度超过20个字符,不启动intern机制

>>> s1 ="a"*20

>>> s2 ="a"*20

>>> s1iss2

True

>>> s1 ="a"*21

>>> s2 ="a"*21

>>> s1iss2

False

>>> s1 ="ab"*10

>>> s2 ="ab"*10

>>> s1iss2

True

>>> s1 ="ab"*11

>>> s2 ="ab"*11

>>> s1iss2

False

-END-

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180905G08VYK00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券