type(x) is list vs type(x) == list



在Python中,假设要测试变量x是否是对列表对象的引用。if type(x) is list:if type(x) == list:之间有区别吗?这就是我的理解。(如果我错了,请纠正我)

  1. type(x) is list测试表达式type(x)list是否计算为同一对象,type(x) == list测试这两个对象是否具有等效(在某种意义上)值
  2. 只要x是列表,type(x) == list就应该评估为True。但是type(x)是否可以评估为与list所指的不同的对象

表达式list的计算结果究竟是什么?(我是Python的新手,来自C++,仍然不能完全理解类型也是对象的概念。)list指向内存中的某个地方吗?那里有什么数据?

;一种明显的方式";这样做将保持";鸭子打字;是CCD_ 15。相反,在大多数情况下,一个人的代码不会特定于列表,而是可以与任何序列一起使用(或者可能需要可变序列)。因此,建议实际上是:

from collections.abc import MutableSequence
... 
if isinstance(x, MutableSequence):
...

现在,进入您的具体问题:

表达式列表的计算结果究竟是什么?列表是否指向内存中的某个位置?那里有什么数据?

Python中的

list指向一个类。一个可以继承、扩展等的类。由于Python的设计选择,创建类实例的语法与调用函数无法区分。因此,在向新手教授Python时,可以随意提及list是一个";函数";(我宁愿不这样做,因为这完全是错误的——函数和类都可以被"调用"并返回结果的通用术语是callable)

作为一个类,list确实生活在记忆中的一个特定位置——";其中";在Python中编码时没有任何区别,但是的,内存中有一个单独的位置,其中一个类(在Python中也是对象,type的实例)作为数据结构存在,该数据结构具有指向Python列表中可以使用的各种方法的指针。

关于:

type(x) is list测试表达式type(x)和list是否计算为同一对象,type(x)==list测试这两个对象是否具有等效(在某种意义上)值。

这是正确的:is是一个特殊的运算符,与其他运算符不同,它不能被任何类覆盖,并检查对象的itentity-在cPython实现中,它检查两个操作数是否位于同一内存地址(但请记住,该地址虽然通过内置函数id可见,但在Python代码中表现得好像是不透明的)。至于";感觉;其中对象是";等于";在Python中:通过在给定对象的类中创建特殊命名的方法__eq__,可以始终覆盖==运算符的行为。(对于每个其他操作符也是如此——语言数据模型列出了所有可用的"魔术"方法)。对于列表,实现的默认比较会自动递归地比较每个元素(当然,如果两个列表中的每个项目对具有相同的大小,则对它们调用.__eq__方法)

type(x)==只要x是一个列表,list就应该计算为True。但是,type(x)是否可以从列表所指的对象评估为不同的对象?

如果"x〃;是一个适当的列表:类型(x)将始终计算为list。但是,如果x是list的子类的实例,或者是另一个Sequence实现,那么==就会失败:这就是为什么使用内置的isinstanceissubclass来比较类总是更好的原因。

is检查确切的身份,并且只有在list类型中只有一个时才有效。幸运的是,list类型也是如此(除非你做了一些愚蠢的事情),所以它通常是有效的。

==测试标准相等性,对于包括list在内的大多数类型,与is等效

综合来看,type(x) is listtype(x) == list之间没有有效的区别,但以前的is结构更好地描述了引擎盖下发生的事情。

考虑避免使用type(x) is sometype构造而使用isinstance函数,因为它也适用于继承类:

x = [1, 2, 3]
isinstance(x, list)  # True
class Y(list):
'''A class that inherits from list'''
...
y = Y([1, 2, 3])
isinstance(y, list)  # True
type(y) is list  # False

更好的是,如果你真的只是想看看某个东西是否像一样在列表中,那么使用isinstancetypingcollections.abc,就像这样:

import collections.abc
x = [1, 2, 3]
isinstance(x, collections.abc.Iterable)  # True
isinstance(x, collections.abc.Sequence)  # True
x = set([1, 2, 3])
isinstance(x, collections.abc.Iterable)  # True
isinstance(x, collections.abc.Sequence)  # False

注意,列表是Iterable(可用于for循环)和Sequence(有序)。setIterable,但不是Sequence,因为您可以在for循环中使用它,但它没有任何特定的顺序。如果要在for循环中使用,请使用Iterable;如果列表必须按特定顺序排列,则使用Sequence

最后注意:dict类型是Mapping,但也算作Iterable,因为您可以在for循环中循环它的键。

最新更新