Python 3.10中多次调用object()为何id有时相同有时不同?
Python中object()实例ID的奇怪现象与哨兵值安全性验证
问题现象
在Python 3.10中出现以下两种不同的执行结果:
- 执行
id(object()), id(object())返回(4519407312, 4519407312)(具体ID值不固定) - 执行
object() is object()返回False
原因分析
这是Python临时对象重用机制导致的:
- 在
id(object()), id(object())表达式中,两个object()创建的都是无引用的临时对象,创建后立即成为垃圾回收候选。Python解释器会在同一表达式求值过程中,重用刚被销毁的临时对象内存地址,因此两个实例ID相同。 - 而
object() is object()的执行逻辑是:先创建第一个object()实例,该实例需要参与后续的is比较,不会被立即销毁;接着创建第二个object()实例时,解释器必须分配新的内存地址,因此is判断返回False。
哨兵值的安全性验证
你提到用object()作为哨兵值的编码模式,担心外部导入的对象会和_UNDEFINED的ID冲突,导致判断错误。结论是:这种情况不可能发生。
具体原因:
- 你定义的
_UNDEFINED = object()是被变量持有的实例,它始终有引用,不会被垃圾回收,内存地址会一直被占用。 - 外部代码调用
object()创建的新实例,要么是无引用的临时对象(用完即销毁,但不会和被引用的_UNDEFINED共用地址),要么是被外部变量持有的实例(会占用新的内存地址)。 - 只有无引用的临时对象才会被重用地址,而
_UNDEFINED始终处于被引用状态,所以永远不会有其他被引用的对象和它ID相同。
你的示例代码中的判断if possibly_overwritten is not _UNDEFINED:是完全安全的,不会出现误判。
内容的提问来源于stack exchange,提问作者Han Qi
相关产品推荐
相关产品推荐

