0

0

Python 中比较绑定方法的正确方式:为什么 == 有效而 is 失败

聖光之護

聖光之護

发布时间:2026-02-18 20:08:02

|

782人浏览过

|

来源于php中文网

原创

Python 中比较绑定方法的正确方式:为什么 == 有效而 is 失败

在 Python 中,通过实例访问的方法(如 obj.method)每次都会创建新的绑定方法对象,因此用 is 比较必然失败;而 == 会基于实例和函数的双重一致性进行语义相等判断,这才是安全可靠的比较方式。

python 中,通过实例访问的方法(如 `obj.method`)每次都会创建新的绑定方法对象,因此用 `is` 比较必然失败;而 `==` 会基于实例和函数的双重一致性进行语义相等判断,这才是安全可靠的比较方式。

在实际开发中(尤其是 Qt、多线程或回调注册场景),我们常需判断传入的回调函数是否等于某个预定义方法,例如:

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,则始终返回 False——即使逻辑上“是同一个方法”。原因在于 Python 的方法绑定机制。

? 绑定方法的本质:每次访问都新建对象

当通过实例访问方法时(如 self.mpositioner.movetostart),Python 动态生成一个 bound method 对象,它内部封装了两个关键属性:

  • __self__: 调用该方法的实例(如 self.mpositioner);
  • __func__: 原始函数对象(即类中定义的 movetostart 函数)。

重要的是:每次点号访问都会创建一个全新的 bound method 实例

立即学习Python免费学习笔记(深入)”;

>>> foo = Foo()
>>> foo.bar is foo.bar  # ❌ 总是 False —— 两个不同对象
False
>>> id(foo.bar) == id(foo.bar)  # ⚠️ 不可靠!因前一个对象已被垃圾回收
True  # (仅因内存复用,非同一对象)

这解释了你测试中观察到的现象:

闪光简历
闪光简历

一款专业的智能AI简历制作工具

下载
callback id: 1890339656832
callback_fun id: 1890339659712  # 地址不同 → 是两个独立对象

✅ == 为何能成功?—— 基于语义的相等性

Python 为 bound method 实现了 __eq__ 方法:两个 bound method 被视为相等,当且仅当它们的 __self__ 和 __func__ 完全相同(使用 is 判断):

>>> foo1 = Foo(); foo2 = Foo()
>>> foo1.bar == foo1.bar  # ✅ True:同一实例 + 同一函数
True
>>> foo1.bar == foo2.bar  # ❌ False:不同实例
False
>>> Foo.bar == Foo.bar    # ✅ True:函数对象本身是单例
True

因此,func_to_execute == self.mpositioner.movetostart 实际在验证:

  • 传入的 func_to_execute 是否也是一个 bound method;
  • 它的 __self__ 是否与 self.mpositioner 是同一对象;
  • 它的 __func__ 是否与 MotorPositioner.movetostart 是同一函数。

这正是业务逻辑所需的行为一致性判断,而非内存地址一致性。

⚠️ 注意事项与最佳实践

  • 永远不要对 bound method 使用 is:它检测的是对象身份(identity),而 bound method 天然不具备跨访问的身份稳定性。
  • 避免依赖 id() 或 hash() 进行逻辑判断:如示例所示,id() 可能因对象快速回收而复用,导致误判。
  • 如需高性能/确定性比较,可显式提取并比对核心组件(进阶用法):
    def is_same_bound_method(a, b):
        return (hasattr(a, '__func__') and hasattr(b, '__func__') and
                a.__func__ is b.__func__ and a.__self__ is b.__self__)

    但通常直接使用 == 更简洁、可读且符合 Python 惯例。

  • 静态方法(@staticmethod)和类方法(@classmethod)不适用此规则:它们不绑定实例,访问时返回的是函数或类方法对象,其身份更稳定(但仍建议优先用 == 保持一致性)。

? 总结

比较方式 适用场景 是否推荐用于 bound method
is 检查是否为同一内存对象(如 x is None) ❌ 绝对不推荐
== 检查逻辑相等性(Python 已为 bound method 正确定义) ✅ 强烈推荐

记住:== 判断“是不是同一个调用意图”,is 判断“是不是同一个内存块”。在回调匹配、信号槽连接、策略选择等场景中,你关心的是前者——而 Python 的 == 正为此而生。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
视频后缀名都有哪些
视频后缀名都有哪些

视频后缀名都有avi、mpg、mpeg、rm、rmvb、flv、wmv、mov、mkv、ASF、M1V、M2V、MPE、QT、VOB、RA、RMJ、RMS、RAM、等等。更多关于视频后缀名的相关知识,详情请看本专题下面的文章,php中文网欢迎大家前来学习。

3744

2023.10.31

C++ Qt图形开发
C++ Qt图形开发

本专题专注于 C++ Qt框架在图形界面开发中的应用,系统讲解窗口设计、信号与槽机制、界面布局、事件处理、数据库连接与跨平台打包等核心技能,通过多个桌面应用项目实战,帮助学员快速掌握 Qt 框架并独立完成跨平台GUI软件的开发。

72

2025.08.15

C++ 图形界面开发基础(Qt方向)
C++ 图形界面开发基础(Qt方向)

本专题系统讲解 使用 C++ 与 Qt 进行图形界面(GUI)开发的核心技能,内容涵盖 Qt 项目结构、窗口组件、信号与槽机制、事件处理、布局管理、资源管理,以及跨平台编译与打包流程。通过多个小型桌面应用实战案例,帮助学习者掌握从界面设计到功能实现的完整 GUI 开发能力。

91

2025.12.05

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

675

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

366

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

26

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

24

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

98

2026.02.06

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

561

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 4.4万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号