python基础:isinstance的使用细节,以及常用类型判断所使用的包 |
您所在的位置:网站首页 › python里面的type怎么用 › python基础:isinstance的使用细节,以及常用类型判断所使用的包 |
目录 前言 一、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 |