【问题标题】:When comparing types/classes, is it "safe" to use the 'is' operator instead of the '==' operator? [duplicate]在比较类型/类时,使用“is”运算符而不是“==”运算符是否“安全”? [复制]
【发布时间】:2017-07-21 05:18:33
【问题描述】:

我不认为这是重复的,因为我在比较类型的特定情况中询问is vs ==,但请告诉我,我会删除问题。

我知道 python 中的is 操作符确实转换为id(type(a))==id(<type>);但到目前为止,我发现type(a) is <type> 似乎给出了可预测的结果。我的问题是,使用is 运算符会产生意想不到的结果(即类似'foo' is str 返回False)?或者python是否将type类存储在可预测的位置,以便is总是给出与==相同的结果?我发现is 在这种情况下更具可读性。

注意这种情况是如果我不处理继承的类/子类(在这种情况下isinstance 是合适的)。

【问题讨论】:

  • 不要将is 视为id 的比较。如果ab 是同一个对象,a is b 的计算结果为True。如果这就是您要寻找的东西,请继续使用它。
  • 尤其是内存位置是完全不相关的。在 CPython 以外的 Python 实现中,它们甚至可能在表达式中间发生变化(尽管 id 值不会)。
  • @user2357112 抱歉,我在多个 stackoverflow 线程中听到了这种解释;我想只有在有限的情况下,这些操作是等价的。
  • 一个类也是type类型的对象。在 Python 中——一切都是对象——所以我认为它应该是安全的。
  • 好吧,如果上下文是 CPython,那是有效的,尽管它是一个实现细节(不太可能改变,但你仍然不应该依赖它)。

标签: python python-3.x class types subclass


【解决方案1】:

不,使用is 总是做同样的事情,它比较(在(C)Python 中)您提供的对象的地址。不可能重新定义is,所以你总是得到相同的行为。

如果两个对象ab 具有与其类型相同的对象,使用type(a) is type(b)总是返回True。相反,如果type(a) is type(b) 保证它们的类型会匹配。

另一方面,== 可能会导致意想不到的结果,如果有人过来并定义了一个做傻事的 __eq__

class MetaFoo(type):
    def __eq__(self, other):
        return False

class Foo(metaclass=MetaFoo):
    pass

f1, f2 = Foo(), Foo()

现在:

type(f1) == type(f2)
False

但是:

type(f1) is type(f2)
True

但人们不会这样做,这很愚蠢。所以type(f1) == type(f2) 不保证任何东西(即对于非内置)。

一般来说,如果您关心它们是完全相同的对象(如评论中所述),请使用is,如果您关心它们的行为方式相同(您希望它们具有相同的行为) __eq__ 待实现)使用==

【讨论】:

  • @StefanPochmann 地址类型? is(导致id)不关心你给它什么,它的行为方式相同。 == 导致 __eq__ 不关心它是实例、类还是元类,它仍然可以有一个奇怪的实现,导致意想不到的结果。也许我误解了这个问题?我不确定。
  • 好吧,问题是关于类型的。以及如何检查它们。我想他想知道对象a 是否有可能具有t 类型但type(a) is t 返回False
  • 我认为更好但仍然没有真正回答这个问题。你说的是“如果两个对象a和b的类型相同”,但应该说“如果两个对象a和b的类型相同”
猜你喜欢
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 2022-12-09
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
  • 1970-01-01
相关资源
最近更新 更多