__instancecheck__与__subclasscheck__:类方法还是实例方法?
instancecheck 和 subclasscheck 的参数定义到底是 self 还是 cls?
核心结论是:两种写法本质等价,只是命名习惯差异——它们是元类的实例方法,第一个参数接收的是「要进行检查的类对象」:
- Python语言参考里用
self,是从「元类的实例方法」的角度命名:元类的实例就是普通类,所以self指代这个类对象。 - PEP 3119里用
cls,是从「功能语义」的角度命名:直接表明这个参数是要检查的类,更直观。
具体解释
当你需要自定义isinstance()或issubclass()的行为时,必须在元类中实现这两个方法。此时:
- 方法的第一个参数(不管叫
self还是cls)会被传入当前的类对象(也就是使用该元类的类)。 - 示例代码:
这里的class CustomMeta(type): def __instancecheck__(self, instance): # self 就是使用这个元类的类,比如下面的CustomClass return hasattr(instance, 'custom_attr') class CustomClass(metaclass=CustomMeta): passself就等同于PEP示例里的cls,都是指CustomClass这个类对象。
关于你的测试结果
你通过inspect模块的测试显示:
type.__instancecheck__的参数是self,这是因为type本身是Python的内置元类,它的__instancecheck__是元类的实例方法,遵循实例方法的参数命名习惯用self。inspect.ismethod(type.__instancecheck__)返回False,是因为inspect.ismethod()仅判断是否是绑定到普通实例的方法对象,而元类的方法在直接访问时(未绑定到具体类实例),不会被识别为标准的method对象——但这并不影响它的实际功能,当你调用isinstance(obj, SomeClass)时,SomeClass作为type的实例,会自动绑定__instancecheck__方法,此时第一个参数就会传入SomeClass本身。
内容的提问来源于stack exchange,提问作者Quinn Walkingstick-Murphey
相关产品推荐
相关产品推荐

