isinstance(foo,bar)vs type(foo)是bar
一个语义问题,真的。
直到最近,如果我必须对结构进行任何type(obj) is list
,我会使用type(obj) is list
et。 人。 然而,自从加入后,我注意到每个人(我的意思是每个人)都使用isinstance(obj,list)
。 看起来它们是同义词, timeit
揭示了它们之间几乎相同的速度。
def a(): return type(list()) is list
def b(): return isinstance(list(),list)
from timeit import timeit
timeit(a)
# 0.5239454597495582
timeit(b)
# 0.5021292075273176
事实上甚至dis
同意它们是同义词,但type is
的例外type is
COMPARE_OP
from dis import dis
dis(a)
# 2 0 LOAD_GLOBAL 0 (type)
# 3 LOAD_GLOBAL 1 (list)
# 6 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
# 9 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
# 12 LOAD_GLOBAL 1 (list)
# 15 COMPARE_OP 8 (is)
# 18 RETURN_VALUE
dis(b)
# 2 0 LOAD_GLOBAL 0 (isinstance)
# 3 LOAD_GLOBAL 1 (list)
# 6 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
# 9 LOAD_GLOBAL 1 (list)
# 12 CALL_FUNCTION 2 (2 positional, 0 keyword pair)
# 15 RETURN_VALUE
我坦率地说, if type(foo) is list:
比if isinstance(foo,list):
更可读if isinstance(foo,list):
第一个基本上只是伪代码,第二个调用某个函数(我必须每次查找isinstance
或instanceof
)与一些参数。 它看起来并不像一个类型转换,而且也知道没有明确的方式是否isinstance(a,b)
被检查是否b
是一个实例a
,反之亦然。
从这个问题我明白,我们使用isinstance
因为它更好地继承。 type(ClassDerivedFromList) is list
将失败,而isinstance(ClassDerivedFromList,list)
将成功。 但是,如果我正在检查什么应该总是一个基础对象,那么我在做什么type is
失去什么?
如果我正在检查什么应该始终是基础对象,那么我在做什么类型时真的会失去什么?
好吧,你给你的问题提供完整的记录答案,这是很好的,所以你的答案是你什么都没有损失! 唯一需要isinstance()
是检查一个给定类与另一个类的继承关系,正如你所说的和引用的那样。 type()
只能用于检查一个实例是否完全是给定的基类型。
除继承问题之外,在使用isinstance
时,您也失去了测试多种类型的能力。 例如:
def chk(typ):
if not isinstance(typ, (str, int)):
raise ValueError('typ must be string or int')
...
你的问题的答案是:
不,考虑到你正在检查一个确定的基类,因为你失去了测试继承类的能力。
IMO的isinstance
更易于阅读和使用Python:可读性计数。
PS:我在时间上有很大的不同(在Python 3.3上)
type: 0.5241982917936874
isinstance: 0.46066255811928847
链接地址: http://www.djcxy.com/p/54239.html