相同Python 3.8.10环境调用类__new__方法一台报错一台正常的原因是什么
异常根本原因
你遇到的报错本质是笔记本全局环境下apt安装的pytest和台式机虚拟环境pip安装的pytest运行逻辑不一致导致的:
- Ubuntu/Debian系操作系统的apt源中提供的pytest包,通常会携带系统自定义补丁,部分旧版本补丁会修改pytest运行时的类加载逻辑,导致你定义的类没有正确隐式继承Python3默认的
object基类 __new__是object基类的内置方法,当类的继承链断开、没有关联到object时,自然会抛出找不到__new__的属性错误- 全局pytest还会加载所有全局安装的pytest第三方插件,部分插件的猴子补丁操作也可能会动态删除类的
__new__属性,触发报错
你忽略的相关知识点
- 不同安装渠道的Python包差异:系统包管理器(apt/yum等)安装的Python包通常会适配系统功能做自定义修改,和PyPI官方源通过pip安装的包功能不完全一致,开发场景下不建议使用系统包管理器安装项目依赖
- 运行环境隔离性:全局Python环境的依赖修改会影响所有运行在全局环境下的代码,虚拟环境可以实现依赖隔离,避免全局环境的不可控变更影响项目运行
- Python3类继承规则:Python3中定义的类默认会隐式继承
object,但如果运行时的类加载逻辑被修改,隐式继承可能失效,显式声明继承object可以规避这类兼容问题 - pytest运行机制:pytest启动时会加载所有已安装的插件并执行钩子逻辑,插件可以修改测试代码的导入、定义、运行全流程,环境中安装的插件不同,代码运行结果可能完全不同
修复方案
- 卸载全局apt安装的pytest:
sudo apt remove python3-pytest - 所有项目依赖都安装在对应虚拟环境中,使用虚拟环境内的pytest执行测试
- 可以给自定义类显式添加
object继承,强制绑定继承链:
class Object(object): def __init__(self): pass def copy(self): cls = self.__class__ result = cls.__new__(cls) ... return result
内容的提问来源于stack exchange,提问作者Iustinian Olaru
相关产品推荐
相关产品推荐

