Python 2调用元类__instancecheck__但Python 3不调用的问题排查
问题解析:Python 2 vs 3 中元类
__instancecheck__方法的调用差异 嘿,这个问题我之前也研究过,其实核心原因很简单——Python 3 里元类的声明方式变了,你的代码在Python 3里根本没把MyMeta设为MyClass的元类,所以__instancecheck__自然没被调用啦。
为啥Python 3里没触发__instancecheck__?
在Python 2中,我们是通过类内部的__metaclass__属性指定元类的,但Python 3彻底废弃了这种写法,换成了类定义时的metaclass关键字参数。你写的代码还是沿用了Python 2的老写法:
class MyClass(object): __metaclass__ = MyMeta
在Python 3环境里,这个__metaclass__属性不会被识别,MyClass还是用默认的type作为元类,那isinstance(1, MyClass)当然直接返回False,根本不会走到MyMeta的__instancecheck__方法里。
改成Python 3兼容的写法就好啦
把元类声明换成Python 3的格式:
class MyMeta(type): def __instancecheck__(cls, instance): print('Checking instance') return True class MyClass(object, metaclass=MyMeta): pass print(isinstance(1, MyClass))
运行这段代码,Python 3里就会输出:
Checking instance True
和Python 2的行为完全一致了。
额外提一句
虽然Python 2和3关于__instancecheck__的文档描述看起来一样,但元类的声明机制是两者的关键差异点之一。如果要写兼容两个版本的代码,可以用six.add_metaclass装饰器,不过这里只要明确不同版本的写法就能解决问题啦。
内容的提问来源于stack exchange,提问作者Jeremy McGibbon
相关产品推荐
相关产品推荐

