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

您所在的位置:网站首页 python里面的type怎么用 python基础:isinstance的使用细节,以及常用类型判断所使用的包

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

2023-09-30 14:08| 来源: 网络整理| 查看: 265

目录

前言

一、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等等特性



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3