繁体   English   中英

type(x) 是列表 vs type(x) == list

[英]type(x) is list vs type(x) == list

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

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

表达式list的确切计算结果是什么? (我是 Python 的新手,来自 C++,但我仍然无法完全理解类型也是对象的概念。) list是否指向 ZCD69B4957F06CD818D7BF3D61980 中的某个地方? 那里有什么数据?

做到这一点的“一种明显的方法”是isinstance(x, list) ,它将保留“鸭子打字”的精神。 相反,在大多数情况下,一个人的代码不会特定于列表,而是可以与任何序列一起使用(或者它可能需要一个可变序列)。 所以建议实际上是:

from collections.abc import MutableSequence

... 

if isinstance(x, MutableSequence):
   ...

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

表达式列表的确切计算结果是什么? 列表是否指向 memory 中的某处? 那里有什么数据?

Python 中的list指向 class。 A class that can be inherited, extended, etc...and thanks to a design choice of Python, the syntax for creating an instance of a class is indistinguishable from calling a function. 因此,在向新手教授 Python 时,可以随便提到list是一个“函数”(我不喜欢,因为它是完全错误的 - 函数和类的通用术语,因为它们可以被“调用”并且将返回一个结果是callable的)

Being a class, list does live in a specific place in memory - the "where" does not make any difference when coding in Python - but yes, there is one single place in memory where a class, which in Python is also an object, type的一个实例,作为一个数据结构存在,带有指向可以在 Python 列表中使用的各种方法的指针。

至于:

type(x) is list测试表达式 type(x) 和 list 的计算结果是否相同 object 和 type(x) == list 测试两个对象是否具有等效(在某种意义上)值。

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

type(x) == list 只要 x 是一个列表,就应该评估为 True。 但是 type(x) 可以评估为不同于列表所指的 object 吗?

如果 "x" 是一个正确的列表,则不是: type(x) 将始终评估为list 但是,如果 x 是list的子类或另一个 Sequence 实现的实例, ==会失败:这就是为什么使用内置的isinstanceissubclass比较类总是更好的原因。

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

==测试标准相等性, is大多数类型,包括list

综上所述, type(x) is listtype(x) == list之间没有有效的区别,但前者is构造更好地描述了幕后发生的事情。

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

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

更好的是,如果您真的只是想查看某些内容是否类似于列表,则使用isinstance typingcollections.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循环中遍历它的键。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM