Python中isinstance()
和type()
的区别是什么?
type()
用于类型检查,而isinstance()
用于对象实例检查。
isinstance(obj, Base)
允许子类的实例和多个可能的基类:
isinstance(obj, (Base1, Base2))
与之相反的是使用类型检查
type(obj) is Base
仅支持所引用的类型。
顺便提一下,is
可能比
更加合适。type(obj) == Base
因为类是单例的。
避免类型检查 - 使用多态(鸭子类型)
在Python中,通常希望允许任何类型的参数,并将其视为期望的,如果对象的行为与预期不符,则会引发适当的错误。这被称为多态,也称为鸭子类型。
def function_of_duck(duck):
duck.quack()
duck.swim()
如果上面的代码可以运行,我们可以推断出我们的参数是一只鸭子。因此,我们可以传入其他实际是鸭子子类型的东西:
function_of_duck(mallard)
或者像鸭子一样工作:
function_of_duck(object_that_quacks_and_swims_like_a_duck)
而我们的代码仍然可以工作。
然而,有些情况下明确地进行类型检查是有必要的。也许您有不同对象类型的合理操作。例如,Pandas Dataframe对象可以从字典或记录构建。在这种情况下,您的代码需要知道它获得的参数类型,以便可以正确处理它。
因此,回答这个问题:
Python中isinstance()
和type()
之间的区别?
请允许我演示一下区别:
type
假设您需要确保函数在获得某种类型的参数时具有特定行为(构造函数的常见用例)。如果您像这样检查类型:
def foo(data):
'''accepts a dict to construct something, string support in future'''
if type(data) is not dict:
# we're only going to test for dicts for now
raise ValueError('only dicts are supported for now')
如果我们试图传入一个 dict
的子类(如果我们期望我们的代码遵循 Liskov替换原则,即子类型可以替换类型),我们的代码就会失败!:
from collections import OrderedDict
foo(OrderedDict([('foo', 'bar'), ('fizz', 'buzz')]))
引发错误!
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in foo
ValueError: argument must be a dict
isinstance
但如果我们使用isinstance
,就可以支持Liskov替换原则!
def foo(a_dict):
if not isinstance(a_dict, dict):
raise ValueError('argument must be a dict')
return a_dict
foo(OrderedDict([('foo', 'bar'), ('fizz', 'buzz')]))
返回 OrderedDict([('foo', 'bar'), ('fizz', 'buzz')])
抽象基类
实际上,我们可以做得更好。 collections
提供了强制各种类型的最小协议的抽象基类。在我们的情况下,如果我们只期望使用 Mapping
协议,我们可以这样做,使我们的代码变得更加灵活:
from collections import Mapping
def foo(a_dict):
if not isinstance(a_dict, Mapping):
raise ValueError('argument must be a dict')
return a_dict
回应评论:
需要注意的是,可以使用type(obj) in (A, B, C)
来检查多个类的类型。
是的,您可以测试类型的相等性,但除非您仅允许那些类型,否则请使用多个基础控制流。
isinstance(obj, (A, B, C))
区别在于 isinstance
支持子类作为父类的替代品而不会破坏程序的其他部分,这个属性被称为 Liskov 替换原则。
更好的方法是,反转你的依赖关系,根本不检查特定类型。
结论
因此,由于我们希望支持替代子类,大多数情况下,我们要避免使用 type
进行类型检查,并优先考虑使用 isinstance
进行类型检查——除非您确实需要知道实例的精确类。
str
和unicode
(在这种情况下您可以使用basestring
进行检查),则可以使用元组来检查多个类型。要检查something
是否为int
或str
,请使用isinstance(something,(int,str))
。 - xuiqzytype()
返回您作为参数输入的对象的类型,通常不太有用,除非与实际类型(例如type(9) == int
)进行比较。isinstance()
根据对象是否属于给定类型返回布尔值 - true 或 false。 对于大多数情况,使用isinstance
通常比编写混乱的等式检查更加优雅。 - user11991978