应优先用==比较值,仅检查None、True、False或单例对象时用is;小整数和字符串的is行为属CPython实现细节,不可依赖;自定义类需实现__eq__和__hash__以支持值比较与哈希。

is 比较的是对象身份(内存地址),== 比较的是值相等;绝大多数场景该用 ==,仅当明确需要判断是否为同一对象时才用 is。
什么时候必须用 is:检查是否为 None 或单例
Python 中 None、True、False 是单例对象,用 is 判断最安全、最快,且符合 PEP 8 推荐。
错误写法:if x == None: —— 这会调用 x.__eq__(None),可能被重载导致意外行为(比如自定义类返回 True)。
正确写法:if x is None:
立即学习“Python免费学习笔记(深入)”;
其他类似场景:
-
if obj is True:(不用obj == True,避免把1或[1]等真值误判) -
if config is DEFAULT_CONFIG:(确认是同一配置实例,而非值相同)
为什么 is 在小整数和短字符串上“偶尔”成立?
这是 CPython 的实现细节(小整数缓存 [-5, 256]、字符串驻留机制),不是语言规范,绝不能依赖。
示例:
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
>>> a = 256 >>> b = 256 >>> a is b True >>> c = 257 >>> d = 257 >>> c is d False # 同样值,不同对象 >>> s1 = "hello" >>> s2 = "hello" >>> s1 is s2 True # 可能成立(驻留) >>> s3 = "hello world" >>> s4 = "hello world" >>> s3 is s4 False # 不一定成立(尤其含空格或运行时拼接)
所以:is 不是用来“优化字符串比较”的,== 才是语义正确的选择。
自定义类中如何控制 == 的行为?
== 默认调用 object.__eq__,它等价于 is(即只比身份)。要按值比较,必须显式实现 __eq__ 方法。
常见疏漏:
- 只实现
__eq__但没实现__hash__→ 实例无法放入set或作dict键(若需不可变语义) -
__eq__中未处理other类型 → 和不同类比较时抛AttributeError或静默返回NotImplemented - 忽略
None边界:应先if other is None: return False,避免后续属性访问失败
简例:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
<pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">def __eq__(self, other):
if not isinstance(other, Point):
return NotImplemented
return self.x == other.x and self.y == other.y
def __hash__(self):
return hash((self.x, self.y))</code></pre>容易踩的坑:布尔上下文混淆 is 和 <code>==
写 if x is True: 和 if x: 完全不是一回事:
-
if x:触发bool(x),对空容器、0、None等返回False -
if x is True:只有当x确实是那个唯一的True对象时才为真,1、[1]、"a"都不满足
所以除非你**明确排斥所有真值、只接受字面量 True**,否则别这么写。同理,if x is False 也极少合理。
更隐蔽的坑:在类型提示或文档里写 “returns True or False”,结果函数实际返回 1/0 或自定义布尔类——这时 is True 就会失效。

















