专栏名称: 老齐Py
Data Science
目录
相关文章推荐
金融街老裘  ·  东方财富2024年年报点评 ·  11 小时前  
幸福东台  ·  22:00至第二天8:00,禁止! ·  昨天  
安全学习那些事儿  ·  国家标准《互联网金融个人网络消费信贷 ... ·  3 天前  
安全学习那些事儿  ·  国家标准《互联网金融个人网络消费信贷 ... ·  3 天前  
51好读  ›  专栏  ›  老齐Py

【译】Python中的 `!=`与`is not`不同

老齐Py  · 掘金  ·  · 2020-02-10 02:51

正文

阅读 17

【译】Python中的 `!=`与`is not`不同

翻译:老齐

与本文内容配套的图书:《跟老齐学Python:轻松入门》《Python大学实用教程》,各大电商平台有售。


Python中的 is == 是不一样的。使用 is 可以比较数字,代码也正常运行。也有人说 is == 要更快,或者你可能觉得它看起来更像Python。然而,重要的是要记住这些运算符的行为并不完全相同。

== 用于比较两个对象的值是否相等,而 is 检查两个变量是否指向内存中的同一个对象。在大多数情况下,这意味着你应该使用 == != ,除非与 None 进行比较。

在本文中,你将学习:

  • 对象相等和同一性的区别是什么
  • 何时使用 == is 比较对象
  • 这些Python运算符的原理是什么
  • 为什么使用 is is not 比较值会导致意外
  • 如何编写自定义的 __eq__() 类方法来定义相等运算符行为

介绍 is is not 的应用

is is not 用来比较两个对象。在CPython中,比较的是对象的内存地址。Python中的一切都是对象,每个对象都存储在特定的内存位置, is is not '检查两个变量是否引用内存中的同一个对象。

注意: 记住,具有相同值的对象可能存储在不同的内存地址中。

你可以使用 id() 来检查一个对象的内存地址:

>>> help(id)
Help on built-in function id in module builtins:

id(obj, /)
    Return the identity of an object.

    This is guaranteed to be unique among simultaneously existing objects.
    (CPython uses the object's memory address.)

>>> id(id)
2570892442576
复制代码

最后一行显示存储内置函数 id 本身的内存地址。

通常,具有相同值的对象在默认情况下具有相同的id。例如,数字-5到256在CPython中被保存,每个数字都存储在内存中单一且固定的位置,这为常用整数节省了内存。

你可以使用 sys.intern() 来保存字符串以提高性能,此函数允许你比较它们的内存地址,而不是对字符串里的字符进行逐个比较:

>>> from sys import intern
>>> a = 'hello world'
>>> b = 'hello world'
>>> a is b
False
>>> id(a)
1603648396784
>>> id(b)
1603648426160

>>> a = intern(a)
>>> b = intern(b)
>>> a is b
True
>>> id(a)
1603648396784
>>> id(b)
1603648396784
复制代码

变量 a b 最初指向内存中的两个不同对象,如它们的不同id所示。使用 intern 后, a b 则指向内存中的同一对象。在原来的操作中,两个 'hello world' 分别在新的内存位置创建对象,但是,对同样的字符串执行 intern 后,后面所创建的字符串所指向的内存地址与第一个 'hello world' 的内存地址相同。

注意:即使对象的内存地址在任何给定的时间都是唯一的,但这个内存地址在同一代码的不同运行过程中是不同的,并且取决于CPython的版本和运行代码的计算机。

默认情况下,具有 intern 效果的对象是 None True False 和简单字符串。请记住,大多数情况下,具有相同值的不同对象将存储在不同的内存地址中,这意味着你不应该使用 is 来比较值。

存储整数

Python将常用的值(例如,整数-5到256)默认保存在内存中,从而节省内存开支。下面的代码向你展示了为什么只有一些整数具有固定的内存地址:

>>> a = 256
>>> b = 256
>>> a is b
True
>>> id(a)
1638894624
>>> id(b)
1638894624

>>> a = 257
>>> b = 257
>>> a is b
False

>>> id(a)
2570926051952
>>> id(b)
2570926051984
复制代码

最初, a b 引用内存中的同一个存储对象,但当它们的值超出常用整数的范围(从-5到256)时,它们就存储在不同的内存地址中。

当多个变量引用同一对象时

用赋值运算符( = )使一个变量等于另一个变量时,可以使这些变量指向内存中的同一对象。这可能会导致可变对象出现意外行为:







请到「今天看啥」查看全文