python基础:isinstance的使用细节,以及常用类型判断所使用的包

本文详细介绍了Python内置函数isinstance的使用,包括其基本语法和用法,强调了isinstance考虑继承关系的特点。文章还探讨了在实际工程中常用的classinfo,特别是typing模块中的数据类型,并提及了numbers模块中的Number类。此外,文章揭示了isinstance的内部判断机制,基于鸭子类型的原理,通过实例展示了如何通过实现特定方法来满足类型判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

一、isinstance的基本使用

1、语法

2、基本用法

二、常用的classinfo

三、isinstance的内部判断机制


前言

isinstance相信大家都已经很熟悉了,对于他的用法和一些基本的操作,我们再做一个介绍。

但是我今天最想和大家将的其实是isinstance(object, classinfo) 中的classinfo都有哪些类型,int、str、dict、bool、list等这些基本类型都是一些最基本的,本文将告诉大家一些常用的classinfo,以及isinstance它的内部到底是怎样一个判断机制。

一、isinstance的基本使用

1、语法

isinstance(object, classinfo)
  • object -- 实例对象。
  • classinfo -- 可以是直接或间接类名、基本类型或者由它们组成的元组。

注意到lclassinfo这个参数的描述,可以是直接或间接类名,这个其实是因为isinstance的判断机制决定的,后面回过头来看你就明白了。

返回值:如果对象的类型与参数二的类型(classinfo)相同则返回 True,否则返回 False。。

2、基本用法

>>>a = 2
>>> isinstance (a,int)
True
>>> isinstance (a,str)
False
>>> isinstance (a,(str,int,list))    # 是元组中的一个返回 True
True

 

isinstance() 与 type() 区别:

  • type() 不会认为子类是一种父类类型,不考虑继承关系。

  • isinstance() 会认为子类是一种父类类型,考虑继承关系。

如果要判断两个类型是否相同推荐使用 isinstance()。

class A:
    pass
 
class B(A):
    pass
 
isinstance(A(), A)    # returns True
type(A()) == A        # returns True
isinstance(B(), A)    # returns True
type(B()) == A        # returns False

二、常用的classinfo

我们常见的classinfo有

    int,float,bool,complex,str(字符串),list,dict(字典),set,tuple

         但是,在实际工程中,其实这些用的并不多。用的比较多的首先是 判断类的实例,这种就不介绍了。另外工程中用的还比较多的就是typing模块中的一套数据类型。关于tying模块,又不熟悉的小伙伴可以看我这篇文章《python高级模块包之typing》。

我列出typing中我们常用的classinfo,当然一下也只是一些常用的,还有很多我没有列出来。并且,有兴趣的人可以去看一下typing的源码,它里里面的容器类型其实都是从collections导入的。所以说下面的数据类型是typing和collections的合集也是正确的。

Dict, Tuple, List
Iterable,Iterator,Generator,Hashable,Sized,Mapping,Sequence,Set,Dict
Coroutine,Awaitable

除了上面,我还要提一个数据类型,Number。在我们验证一个类型是不是数字时,可以使用下面两种方法:

>>> a = 1.1
>>> b = 1
>>> isinstance(a, (int, float))
True
>>> isinstance(b, (int, float))
True
#*********************************#
>>> from numbers import Number
>>> isinstance(a, Number)
True
>>> isinstance(b, Number)
True

当然,numbers模块中还有其他的数据类型,如Complex(复数类型),Intergral(整数类型)。都可以用在isinstance上。

那么,大家有没有想过,为什么我去判断一个数是不是整数,classinfo可以有int、Intergral甚至更多个classinfo呢?其实答案就在我们前面提到的,classinfo可以是直接或者间接类名。

三、isinstance的内部判断机制

这里是参考的一篇网上的文章,出处:http://www.manongjc.com/detail/13-feratkzldglpqji.html

我觉得,需要先铺垫一个概念,就是-鸭子类型。不会的可以再去理解一下。

我们通常说的,这个类型是不是iterable,是不是gengerator,其实就是看它内部是否实现了某一个或多个指定的方法。只要某个类它实现了这个方法,那他就符合对应的类型。这其实就是鸭子类型的使用。

其实isinstance正是使用了鸭子类型这一点,我们来看下面的分析。

 

type得到的就是具体实例化该对象类,而isinstance则貌似是要求满足某种特定的要件就可以。我们来看一下Iterable源码。

class Iterable(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterable:
            return _check_methods(C, "__iter__")
        return NotImplemented

class Sized(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __len__(self):
        return 0

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Sized:
            return _check_methods(C, "__len__")
        return NotImplemented
    
    
class Container(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __contains__(self, x):
        return False

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Container:
            return _check_methods(C, "__contains__")
        return NotImplemented

我们注意到这些都是一个抽象基类,里面定义了一个__subclasshook__方法,其实关键就在这里。

我们只要满足__subclasshook__的条件,instance就会判断他们是相同的类型。

因此我们自己实现一个类,测试下

from abc import ABCMeta


class A(metaclass=ABCMeta):

    @classmethod
    def __subclasshook__(cls, C):
        # 当我们使用isinstance(obj, A)的时候
        # 那么实例化obj所对应类,就会作为参数传递给C
        # 我们可以自定义,比如这里
        # 如果C有fuck这个属性,那么就认为obj也是A的实例
        return hasattr(C, "fuck")


class S:

    def fuck(self):
        pass


s = S()
print(isinstance(s, A))  # True
# 我们注意到S这个类没有继承任何东西,但是它确是A的实例
# 因为我们自己实现了抽象基类

# 不仅如此,此时的S这个类还是A的子类
print(issubclass(S, A))  # True

这其实也验证了instance的鸭子类型的思想。

所以我们有时候会见到,一个类它即是可迭代的,还是Sized等等特性

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值