Python中比较函数参数与回调函数:为何is运算符失效?
Python对象比较:
==有效但is失效的原因分析 问题代码
class Window(QtWidgets.QMainWindow): def __init__(self): super(Window,self).__init__() uic.loadUi('window.ui', self) self.show() def thread_it(self, func_to_execute): worker = Worker(func_to_execute) if func_to_execute == self.mpositioner.movetostart: worker.signals.progress.connect(self.create_raw_log_line) self.threadpool.start(worker) return worker
核心困惑
仅当使用==运算符判断func_to_execute == self.mpositioner.movetostart时代码有效,使用is运算符则无效。VSCode的Pylint曾建议使用is,但Ruff检查工具对==无报错,想知道is运算符失效是否存在特定原因?
补充测试结果
callback: <bound method MotorPositioner.movetostart of <__main__.MotorPositioner object at 0x000001B81B7C60E0>> callback id: 1890339656832 callback_fun: <bound method MotorPositioner.movetostart of <__main__.MotorPositioner object at 0x000001B81B7C60E0>> callback_fun id: 1890339659712 Yup same function
可见两者指向的是同一方法,但内存ID不同。
原因分析
这是Python中**绑定方法(bound method)**的特性导致的:
- 每次访问实例的方法(比如
self.mpositioner.movetostart)时,Python都会动态创建一个新的bound method包装对象。这个对象会绑定当前实例和原始方法,但每次创建的包装对象内存地址(ID)都不相同。 is运算符的作用是判断两个对象是否为同一个内存实例(即ID完全一致),所以两次生成的绑定方法实例用is比较会返回False。==运算符对于绑定方法会做深层比较:检查两者是否指向同一个原始方法,并且绑定的是同一个实例,因此会返回True。
Pylint建议用is通常针对单例、None这类固定实例的场景,但对于绑定方法,==才是符合需求的正确比较方式,这也是Ruff不对==报错的原因。
内容的提问来源于stack exchange,提问作者Radek D
相关产品推荐
相关产品推荐

