写点什么

Python 中有什么不容易让人察觉的有趣的事实?

作者:Jackpop
  • 2022 年 4 月 09 日
  • 本文字数:1730 字

    阅读完需:约 6 分钟

 提起 Python,绝大多数同学第一印象就是”简单“。

但是,Python 中也有很多有趣、微妙的事情,如果不用心去了解,很容易在开发过程中陷入误区,久久无法自拔。

下面,就介绍几个 Python 中有趣的事情。

1. 微妙的字符串

>>> a = "wtf">>> b = "wtf">>> a is bTrue
>>> a = "wtf!">>> b = "wtf!">>> a is bFalse
>>> a, b = "wtf!", "wtf!">>> a is b True
复制代码


是不是觉得很神奇?

为什么加上!返回就是False,不加则返回True

为什么加上!并放置同一行时,又返回True了?

  • 这些行为是由于 Cpython 在编译优化时, 某些情况下会尝试使用已经存在的不可变对象而不是每次都创建一个新对象. (这种行为被称作字符串的驻留[string interning])

  • 发生驻留之后, 许多变量可能指向内存中的相同字符串对象. (从而节省内存)

  • 在上面的代码中, 字符串是隐式驻留的. 何时发生隐式驻留则取决于具体的实现. 这里有一些方法可以用来猜测字符串是否会被驻留:

    所有长度为 0 和长度为 1 的字符串都被驻留.

    字符串在编译时被实现 ('wtf' 将被驻留, 但是 ''.join(['w', 't', 'f']) 将不会被驻留)

    字符串中只包含字母,数字或下划线时将会驻留. 所以 'wtf!' 由于包含 ! 而未被驻留.

  • 当在同一行将 a 和 b 的值设置为 "wtf!" 的时候, Python 解释器会创建一个新对象, 然后同时引用第二个变量。如果你在不同的行上进行赋值操作, 它就不会“知道”已经有一个 wtf! 对象 (因为 "wtf!" 不是按照上面提到的方式被隐式驻留的). 它是一种编译器优化, 特别适用于交互式环境.

2. is==的区别

>>> a = 256>>> b = 256>>> a is bTrue
>>> a = 257>>> b = 257>>> a is bFalse
>>> a = 257; b = 257>>> a is bTrue
复制代码


  • is 运算符检查两个运算对象是否引用自同一对象 (即, 它检查两个运算对象是否相同).

  • == 运算符比较两个运算对象的值是否相等.

  • 因此is代表引用相同,==代表值相等. 下面的例子可以很好的说明这点,

    >>> [] == [] True >>> [] is [] # 这两个空列表位于不同的内存地址. False

256 是一个已经存在的对象, 而 257 不是

当你启动 Python 的时候, 数值为 -5 到 256 的对象就已经被分配好了. 这些数字因为经常被使用, 所以会被提前准备好.

Python 通过这种创建小整数池的方式来避免小整数频繁的申请和销毁内存空间.

3. is not ... 不是 is (not ...)

>>> 'something' is not NoneTrue>>> 'something' is (not None)False
复制代码


  • is not 是个单独的二元运算符, 与分别使用 is 和 not 不同.

  • 如果操作符两侧的变量指向同一个对象, 则 is not 的结果为 False, 否则结果为 True.

4. 逗号

>>> def f(x, y,):...     print(x, y)...>>> def g(x=4, y=5,):...     print(x, y)...>>> def h(x, **kwargs,):  File "<stdin>", line 1    def h(x, **kwargs,):                     ^SyntaxError: invalid syntax>>> def h(*args,):  File "<stdin>", line 1    def h(*args,):                ^SyntaxError: invalid syntax
复制代码


  • 在 Python 函数的形式参数列表中, 尾随逗号并不一定是合法的.

  • 在 Python 中, 参数列表部分用前置逗号定义, 部分用尾随逗号定义. 这种冲突导致逗号被夹在中间, 没有规则定义它.(译:这一句看得我也很懵逼,只能强翻了.详细解释看下面的讨论帖会一目了然.)

5. 真亦假

True = Falseif True == False:    print("I've lost faith in truth!")
复制代码


输出:

I've lost faith in truth!
复制代码


  • 最初, Python 并没有 bool 型 (人们用 0 表示假值, 用非零值比如 1 作为真值). 后来他们添加了 TrueFalse, 和 bool 型, 但是, 为了向后兼容, 他们没法把 True 和 False 设置为常量, 只是设置成了内置变量.

  • Python 3 由于不再需要向后兼容, 终于可以修复这个问题了, 所以这个例子无法在 Python 3.x 中执行!

这里只是举了几个例子,上面的例子是从 Github 上一个非常火热的开源项目wtfpython节选的,目前该项目已经有 2.8 万+star,受欢迎程度可见一斑。除了英文版,它还有中文版。 

它收集了 Python 中各种各样奇怪且有趣的事情,感兴趣的同学可以花时间多了解一下。


hello,大家好,我是 Jackpop,硕士毕业于哈尔滨工业大学,曾在华为、阿里等大厂工作,如果你对升学、就业、技术提升等有疑惑,不妨交个朋友:

我是Jackpop,我们交个朋友吧!

发布于: 刚刚阅读数: 2
用户头像

Jackpop

关注

还未添加个人签名 2020.09.16 加入

公众号:平凡而诗意,微信:code_7steps,全网粉丝超20万,技术进阶、优质资源、实用工具,欢迎关注!

评论

发布
暂无评论
Python 中有什么不容易让人察觉的有趣的事实?_Jackpop_InfoQ写作平台