python isinstance函数

isinstance(object, classinfo)

用于检查类型

判断 obj 对象是否为 classinfo 对应类型的实例或者其子类的实例,是则返回 True,否则返回 False

  • object 为待检查的对象
  • classinfo 的类型为 Type 或 包含了 Typetuple
  • 如果 classinfo 传入的参数类型不匹配,那么会抛出 TypeError 异常

Python3.10classinfo 类型可以为 Union

isinstance(obj, (A, B, C)) 
# 等同于
isinstance(obj, A) or isinstance(obj, B) or isinstance(obj, C)

遇到的问题

用 Scrapy 写项目时,定义了异常类 ParseError,以及自定义的SpiderMiddleware 用于处理该类异常,使用 isinstance 函数来判断异常是否为 ParseError,发现对于是相同类型的对象, isinstance 仍然返回 False;

输出异常类型以及 ParseError 的信息,发现 <class 'data_scrapy.announcement_scrapy.components.parseerror.ParseError'> <class 'announcement_scrapy.components.parseerror.ParseError'> 二者之间仅相差一个前缀不同,导致了该函数返回 False

后面使用 id() 输出对应类型的值,也是不相等;

def process_spider_exception(self, response, exception, spider: Spider):
    print(type(exception), ParseError)
    # <class 'data_scrapy.announcement_scrapy.components.parseerror.ParseError'> <class 'announcement_scrapy.components.parseerror.ParseError'>
    print(id(exception.__class__), id(ParseError))
    if isinstance(exception, ParseError): # 返回 False
        error = spider.logger.error
        # ...

Python的导入机制会根据导入路径来决定模块的命名空间,即使是同一个模块,如果导入路径不同,Python也会认为它们是两个不同的模块。

统一导入方式防止上述情况发生,在 process_spider_exception 中对 ParseError 加上相同的前缀:data_scrapy.announcement_scrapy.components.parseerror.ParseError 即可

类的重载

如果类发生了重载 reload,也会导致 isinstance 返回False

举个例子:

if __name__ == '__main__':
    class A:
        pass


    a = A()
    print(isinstance(a, A), type(A), id(A))

    class A:
        pass
    print(isinstance(a, A), type(A), id(A))

"""
结果:
True <class 'type'> 2136731130064
False <class 'type'> 2136731139664
"""

例子中可以看到,类发生重载后,即使 type() 返回信息相同,但是 id() 返回信息不同,导致 isinstance() 返回 False

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值