标签归档:semantics

“ ==”和“是”之间有区别吗?

问题:“ ==”和“是”之间有区别吗?

我的Google Fu使我失败了。

在Python中,以下两个相等测试是否等效?

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'

这是否适用于您要比较实例(list说)的对象?

好的,这样可以回答我的问题:

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

因此,==测试会重视在哪里is进行测试以查看它们是否是同一对象?

My Google-fu has failed me.

In Python, are the following two tests for equality equivalent?

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'

Does this hold true for objects where you would be comparing instances (a list say)?

Okay, so this kind of answers my question:

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

So == tests value where is tests to see if they are the same object?


回答 0

isTrue如果两个变量指向同一个对象(==如果变量引用的对象相等),则将返回。

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True

# Make a new copy of list `a` via the slice operator, 
# and assign it to variable `b`
>>> b = a[:] 
>>> b is a
False
>>> b == a
True

在您的情况下,第二项测试仅能工作,因为Python会缓存小的整数对象,这是实现细节。对于较大的整数,这不起作用:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

字符串文字也是如此:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

也请参阅此问题

is will return True if two variables point to the same object, == if the objects referred to by the variables are equal.

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True

# Make a new copy of list `a` via the slice operator, 
# and assign it to variable `b`
>>> b = a[:] 
>>> b is a
False
>>> b == a
True

In your case, the second test only works because Python caches small integer objects, which is an implementation detail. For larger integers, this does not work:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

The same holds true for string literals:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

Please see this question as well.


回答 1

有一条简单的经验法则可以告诉您何时使用==is

  • ==是为了价值平等。当您想知道两个对象是否具有相同的值时,请使用它。
  • is参考平等。当您想知道两个引用是否引用同一对象时,请使用它。

通常,在将某事物与简单类型进行比较时,通常会检查值是否相等,因此应使用==。例如,您的示例的目的可能是检查x是否具有等于2(==)的值,而不是检查x字面上是否指向与2相同的对象。


其他注意事项:由于CPython参考实现的工作方式,如果错误地用于is比较整数的参考相等性,则会得到意外且不一致的结果:

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

这几乎是我们所期望的:a并且b具有相同的值,但是是不同的实体。但是呢?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

这与先前的结果不一致。这里发生了什么?事实证明,出于性能原因,Python的参考实现将-5..256范围内的整数对象作为单例实例进行缓存。这是一个演示此示例:

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

这是另一个不使用的明显原因is:当您错误地将其用于值相等时,该行为应由实现决定。

There is a simple rule of thumb to tell you when to use == or is.

  • == is for value equality. Use it when you would like to know if two objects have the same value.
  • is is for reference equality. Use it when you would like to know if two references refer to the same object.

In general, when you are comparing something to a simple type, you are usually checking for value equality, so you should use ==. For example, the intention of your example is probably to check whether x has a value equal to 2 (==), not whether x is literally referring to the same object as 2.


Something else to note: because of the way the CPython reference implementation works, you’ll get unexpected and inconsistent results if you mistakenly use is to compare for reference equality on integers:

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

That’s pretty much what we expected: a and b have the same value, but are distinct entities. But what about this?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

This is inconsistent with the earlier result. What’s going on here? It turns out the reference implementation of Python caches integer objects in the range -5..256 as singleton instances for performance reasons. Here’s an example demonstrating this:

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

This is another obvious reason not to use is: the behavior is left up to implementations when you’re erroneously using it for value equality.


回答 2

==确定值是否相等,而is确定它们是否是完全相同的对象。

== determines if the values are equal, while is determines if they are the exact same object.


回答 3

==isPython 之间有区别吗?

是的,它们有非常重要的区别。

==:检查是否相等-语义是等效对象(不一定是同一对象)将被测试为相等。如文档所述

运算符<,>,==,> =,<=和!=比较两个对象的值。

is:检查身份-语义是对象(保存在内存中)对象。再次,文档说

运算符isis not对象身份测试:x is y当且仅当xy是相同对象时,才为true 。使用该id()功能确定对象身份。x is not y产生反真值。

因此,对身份的检查与对对象ID的相等性检查相同。那是,

a is b

是相同的:

id(a) == id(b)

where id是返回整数的内建函数,该整数“保证同时存在的对象之间是唯一的”(请参阅​​参考资料help(id)),而where ab则是任意对象。

其他使用说明

您应该将这些比较用于它们的语义。使用is检查身份和==检查平等。

因此,通常,我们使用is来检查身份。当我们检查一个仅在内存中存在一次的对象(在文档中称为“单个”)时,这通常很有用。

用例is包括:

  • None
  • 枚举值(当使用枚举模块中的枚举时)
  • 通常是模块
  • 通常是由类定义产生的类对象
  • 通常由函数定义产生的函数对象
  • 在内存中应该只存在一次的所有其他内容(通常是所有单例)
  • 您希望通过身份获得的特定对象

通常的用例==包括:

  • 数字,包括整数
  • 清单
  • 词典
  • 自定义可变对象
  • 在大多数情况下,其他内置的不可变对象

一般使用情况下,再次对==,就是你想可能不是对象相同的对象,相反,它可能是一个相当于一个

PEP 8方向

PEP 8,标准库的官方Python样式指南还提到了以下两个用例is

与单例之类的比较None应始终使用isis not,而不应使用相等运算符。

另外,当心if x您的意思if x is not None,例如当测试是否将默认None 设置为的变量或参数设置为其他值时,请当心编写。另一个值可能具有在布尔上下文中可能为false的类型(例如容器)!

从身份推断平等

如果is为true,通常可以推断出相等性-从逻辑上讲,如果对象是自身,则它应该测试为等同于自身。

在大多数情况下,此逻辑是正确的,但它依赖于__eq__特殊方法的实现。正如文档所说,

相等比较(==!=)的默认行为基于对象的标识。因此,具有相同身份的实例的相等比较会导致相等,而具有不同身份的实例的相等比较会导致不平等。这种默认行为的动机是希望所有对象都是自反的(即x为y意味着x == y)。

为了保持一致性,建议:

平等比较应该是自反的。换句话说,相同的对象应该比较相等:

x is y 暗示 x == y

我们可以看到这是自定义对象的默认行为:

>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)

相反,通常也是如此-如果某项测试的结果不相等,则通常可以推断出它们不是同一对象。

由于可以对相等性测试进行自定义,因此该推论并不总是适用于所有类型。

一个exceptions

一个显着的exceptions是nan-它总是被测试为不等于自身:

>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan           # !!!!!
False

检查身份比检查相等性要快得多(可能需要递归检查成员)。

但是它不能替代相等性,在相等性中您可能会发现多个对象相等。

请注意,比较列表和元组的相等性将假定对象的身份相同(因为这是一个快速检查)。如果逻辑不一致,这可能会产生矛盾-就是这样nan

>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True

警示故事:

问题是试图is用来比较整数。您不应该假定整数的实例与另一个引用获得的实例相同。这个故事解释了为什么。

一个注释者的代码依赖于以下事实:小整数(包括-5至256)在Python中是单例,而不是检查是否相等。

哇,这可能会导致一些隐患。我有一些检查a是否为b的代码,它可以按我的意愿工作,因为a和b通常很小。该错误仅在生产六个月后才出现在今天,因为a和b最终足够大而无法缓存。– gwg

它在开发中起作用。它可能已经通过了一些单元测试。

它可以在生产中使用-直到代码检查出大于256的整数为止,此时它在生产中失败了。

这是生产失败,可能已在代码审查中或可能通过样式检查器捕获。

让我强调一下:不要is用于比较整数。

Is there a difference between == and is in Python?

Yes, they have a very important difference.

==: check for equality – the semantics are that equivalent objects (that aren’t necessarily the same object) will test as equal. As the documentation says:

The operators <, >, ==, >=, <=, and != compare the values of two objects.

is: check for identity – the semantics are that the object (as held in memory) is the object. Again, the documentation says:

The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. Object identity is determined using the id() function. x is not y yields the inverse truth value.

Thus, the check for identity is the same as checking for the equality of the IDs of the objects. That is,

a is b

is the same as:

id(a) == id(b)

where id is the builtin function that returns an integer that “is guaranteed to be unique among simultaneously existing objects” (see help(id)) and where a and b are any arbitrary objects.

Other Usage Directions

You should use these comparisons for their semantics. Use is to check identity and == to check equality.

So in general, we use is to check for identity. This is usually useful when we are checking for an object that should only exist once in memory, referred to as a “singleton” in the documentation.

Use cases for is include:

  • None
  • enum values (when using Enums from the enum module)
  • usually modules
  • usually class objects resulting from class definitions
  • usually function objects resulting from function definitions
  • anything else that should only exist once in memory (all singletons, generally)
  • a specific object that you want by identity

Usual use cases for == include:

  • numbers, including integers
  • strings
  • lists
  • sets
  • dictionaries
  • custom mutable objects
  • other builtin immutable objects, in most cases

The general use case, again, for ==, is the object you want may not be the same object, instead it may be an equivalent one

PEP 8 directions

PEP 8, the official Python style guide for the standard library also mentions two use-cases for is:

Comparisons to singletons like None should always be done with is or is not, never the equality operators.

Also, beware of writing if x when you really mean if x is not None — e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!

Inferring equality from identity

If is is true, equality can usually be inferred – logically, if an object is itself, then it should test as equivalent to itself.

In most cases this logic is true, but it relies on the implementation of the __eq__ special method. As the docs say,

The default behavior for equality comparison (== and !=) is based on the identity of the objects. Hence, equality comparison of instances with the same identity results in equality, and equality comparison of instances with different identities results in inequality. A motivation for this default behavior is the desire that all objects should be reflexive (i.e. x is y implies x == y).

and in the interests of consistency, recommends:

Equality comparison should be reflexive. In other words, identical objects should compare equal:

x is y implies x == y

We can see that this is the default behavior for custom objects:

>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)

The contrapositive is also usually true – if somethings test as not equal, you can usually infer that they are not the same object.

Since tests for equality can be customized, this inference does not always hold true for all types.

An exception

A notable exception is nan – it always tests as not equal to itself:

>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan           # !!!!!
False

Checking for identity can be much a much quicker check than checking for equality (which might require recursively checking members).

But it cannot be substituted for equality where you may find more than one object as equivalent.

Note that comparing equality of lists and tuples will assume that identity of objects are equal (because this is a fast check). This can create contradictions if the logic is inconsistent – as it is for nan:

>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True

A Cautionary Tale:

The question is attempting to use is to compare integers. You shouldn’t assume that an instance of an integer is the same instance as one obtained by another reference. This story explains why.

A commenter had code that relied on the fact that small integers (-5 to 256 inclusive) are singletons in Python, instead of checking for equality.

Wow, this can lead to some insidious bugs. I had some code that checked if a is b, which worked as I wanted because a and b are typically small numbers. The bug only happened today, after six months in production, because a and b were finally large enough to not be cached. – gwg

It worked in development. It may have passed some unittests.

And it worked in production – until the code checked for an integer larger than 256, at which point it failed in production.

This is a production failure that could have been caught in code review or possibly with a style-checker.

Let me emphasize: do not use is to compare integers.


回答 4

is和之间有什么区别==

==is不同的比较!正如其他人已经说过的:

  • == 比较对象的值。
  • is 比较对象的引用。

在Python中,例如,在这种情况下value1,名称指的是对象,并value2指代int存储值的实例1000

value1 = 1000
value2 = value1

因为value2引用相同的对象is==将给出True

>>> value1 == value2
True
>>> value1 is value2
True

在以下示例中,名称value1value2引用不同的int实例,即使它们都存储相同的整数:

>>> value1 = 1000
>>> value2 = 1000

因为相同的值(整数)存储==将是True,这就是为什么它通常被称为“值比较”。但是is会返回,False因为这些是不同的对象:

>>> value1 == value2
True
>>> value1 is value2
False

什么时候使用?

通常,is比较起来要快得多。这就是为什么CPython缓存(或者最好是重用)某些对象,例如小整数,某些字符串等。但是,这应该被视为实现细节,即使在没有警告的情况下也可以随时更改(即使可能性很小)。

is应在以下情况下使用

  • 想要检查两个对象是否真的是同一对象(不仅仅是相同的“值”)。一个示例可以是如果使用单例对象作为常量。
  • 想比较一个值和一个Python 常量。Python中的常量为:

    • None
    • True1个
    • False1个
    • NotImplemented
    • Ellipsis
    • __debug__
    • 类(例如int is intint is float
    • 内置模块或第三方模块中可能存在其他常量。例如np.ma.masked来自NumPy模块)

其他所有情况下,您都应使用==检查是否相等。

我可以自定义行为吗?

==在其他答案中还没有提到某些方面:它是Python“ Data model”的一部分。这意味着可以使用该__eq__方法自定义其行为。例如:

class MyClass(object):
    def __init__(self, val):
        self._value = val

    def __eq__(self, other):
        print('__eq__ method called')
        try:
            return self._value == other._value
        except AttributeError:
            raise TypeError('Cannot compare {0} to objects of type {1}'
                            .format(type(self), type(other)))

这只是一个人工的例子,用来说明该方法的确是这样的:

>>> MyClass(10) == MyClass(10)
__eq__ method called
True

请注意,默认情况下(如果__eq__在类或超类中找不到的其他实现)则__eq__使用is

class AClass(object):
    def __init__(self, value):
        self._value = value

>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a

因此,实现__eq__您想要的不仅仅是定制类的引用比较,实际上很重要!

另一方面,您无法自定义is检查。它总是会比较公正,如果你有相同的参考。

这些比较是否总是返回布尔值?

由于__eq__可以重新实现或覆盖,因此不限于return TrueFalse。它可以返回任何内容(但是在大多数情况下,它应该返回一个布尔值!)。

例如,对于NumPy数组,==它将返回一个数组:

>>> import numpy as np
>>> np.arange(10) == 2
array([False, False,  True, False, False, False, False, False, False, False], dtype=bool)

但是is支票总是会返回TrueFalse


1正如亚伦·霍尔在评论中提到的那样:

通常,您不应该执行任何操作is Trueis False检查,因为一个人通常在将条件隐式转换为布尔值的上下文中使用这些“检查” (例如,在if语句中)。因此,进行is True比较隐式的布尔类型转换要比仅仅进行布尔类型转换做更多的工作-并且您将自己限制为布尔值(不认为它是pythonic)。

就像PEP8提到的那样:

不要将布尔值与TrueFalse使用进行比较==

Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:

What’s the difference between is and ==?

== and is are different comparison! As others already said:

  • == compares the values of the objects.
  • is compares the references of the objects.

In Python names refer to objects, for example in this case value1 and value2 refer to an int instance storing the value 1000:

value1 = 1000
value2 = value1

Because value2 refers to the same object is and == will give True:

>>> value1 == value2
True
>>> value1 is value2
True

In the following example the names value1 and value2 refer to different int instances, even if both store the same integer:

>>> value1 = 1000
>>> value2 = 1000

Because the same value (integer) is stored == will be True, that’s why it’s often called “value comparison”. However is will return False because these are different objects:

>>> value1 == value2
True
>>> value1 is value2
False

When to use which?

Generally is is a much faster comparison. That’s why CPython caches (or maybe reuses would be the better term) certain objects like small integers, some strings, etc. But this should be treated as implementation detail that could (even if unlikely) change at any point without warning.

You should only use is if you:

  • want to check if two objects are really the same object (not just the same “value”). One example can be if you use a singleton object as constant.
  • want to compare a value to a Python constant. The constants in Python are:

    • None
    • True1
    • False1
    • NotImplemented
    • Ellipsis
    • __debug__
    • classes (for example int is int or int is float)
    • there could be additional constants in built-in modules or 3rd party modules. For example np.ma.masked from the NumPy module)

In every other case you should use == to check for equality.

Can I customize the behavior?

There is some aspect to == that hasn’t been mentioned already in the other answers: It’s part of Pythons “Data model”. That means its behavior can be customized using the __eq__ method. For example:

class MyClass(object):
    def __init__(self, val):
        self._value = val

    def __eq__(self, other):
        print('__eq__ method called')
        try:
            return self._value == other._value
        except AttributeError:
            raise TypeError('Cannot compare {0} to objects of type {1}'
                            .format(type(self), type(other)))

This is just an artificial example to illustrate that the method is really called:

>>> MyClass(10) == MyClass(10)
__eq__ method called
True

Note that by default (if no other implementation of __eq__ can be found in the class or the superclasses) __eq__ uses is:

class AClass(object):
    def __init__(self, value):
        self._value = value

>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a

So it’s actually important to implement __eq__ if you want “more” than just reference-comparison for custom classes!

On the other hand you cannot customize is checks. It will always compare just if you have the same reference.

Will these comparisons always return a boolean?

Because __eq__ can be re-implemented or overridden, it’s not limited to return True or False. It could return anything (but in most cases it should return a boolean!).

For example with NumPy arrays the == will return an array:

>>> import numpy as np
>>> np.arange(10) == 2
array([False, False,  True, False, False, False, False, False, False, False], dtype=bool)

But is checks will always return True or False!


1 As Aaron Hall mentioned in the comments:

Generally you shouldn’t do any is True or is False checks because one normally uses these “checks” in a context that implicitly converts the condition to a boolean (for example in an if statement). So doing the is True comparison and the implicit boolean cast is doing more work than just doing the boolean cast – and you limit yourself to booleans (which isn’t considered pythonic).

Like PEP8 mentions:

Don’t compare boolean values to True or False using ==.

Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:

回答 5

他们是完全不同的is检查对象身份,同时==检查是否相等(一个概念取决于两个操作数的类型)。

幸运的巧合是“ is”似乎可以正确地使用小整数(例如5 == 4 + 1)。那是因为CPython通过使整数成为单例来优化整数存储范围(-5到256)。此行为完全取决于实现,并且不能保证在所有较小的转换操作方式下都可以保留该行为。

例如,Python 3.5还使短字符串单身,但将它们切片会破坏此行为:

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False

They are completely different. is checks for object identity, while == checks for equality (a notion that depends on the two operands’ types).

It is only a lucky coincidence that “is” seems to work correctly with small integers (e.g. 5 == 4+1). That is because CPython optimizes the storage of integers in the range (-5 to 256) by making them singletons. This behavior is totally implementation-dependent and not guaranteed to be preserved under all manner of minor transformative operations.

For example, Python 3.5 also makes short strings singletons, but slicing them disrupts this behavior:

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False

回答 6

https://docs.python.org/library/stdtypes.html#comparisons

is身份 ==测试,是否相等

每个(小)整数值都映射到单个值,因此,每个3都是相同且相等的。这是实现细节,但不是语言规范的一部分

https://docs.python.org/library/stdtypes.html#comparisons

is tests for identity == tests for equality

Each (small) integer value is mapped to a single value, so every 3 is identical and equal. This is an implementation detail, not part of the language spec though


回答 7

您的回答是正确的。该is运算符比较两个对象的身份。该==操作比较两个对象的值。

一旦创建了对象,其身份就不会改变。您可能会认为它是对象在内存中的地址。

您可以通过定义__cmp__方法或丰富的比较方法(例如)来控制对象值的比较行为__eq__

Your answer is correct. The is operator compares the identity of two objects. The == operator compares the values of two objects.

An object’s identity never changes once it has been created; you may think of it as the object’s address in memory.

You can control comparison behaviour of object values by defining a __cmp__ method or a rich comparison method like __eq__.


回答 8

看一下Stack Overflow问题,Python的“ is”运算符在使用整数时表现异常

最主要的原因是“ is”检查它们是否是同一对象,而不只是彼此相等(小于256的数字是特例)。

Have a look at Stack Overflow question Python’s “is” operator behaves unexpectedly with integers.

What it mostly boils down to is that “is” checks to see if they are the same object, not just equal to each other (the numbers below 256 are a special case).


回答 9

简而言之,is检查两个引用是否指向同一对象。==检查两个对象是否具有相同的值。

a=[1,2,3]
b=a        #a and b point to the same object
c=list(a)  #c points to different object 

if a==b:
    print('#')   #output:#
if a is b:
    print('##')  #output:## 
if a==c:
    print('###') #output:## 
if a is c:
    print('####') #no output as c and a point to different object 

In a nutshell, is checks whether two references point to the same object or not.== checks whether two objects have the same value or not.

a=[1,2,3]
b=a        #a and b point to the same object
c=list(a)  #c points to different object 

if a==b:
    print('#')   #output:#
if a is b:
    print('##')  #output:## 
if a==c:
    print('###') #output:## 
if a is c:
    print('####') #no output as c and a point to different object 

回答 10

正如John Feminella所说,大多数时候,您将使用==和!=,因为您的目标是比较值。我只想对剩下的时间做些什么:

NoneType只有一个实例,即None是一个单例。因此foo == Nonefoo is None意思相同。但是,is测试速度更快,并且要使用Pythonic约定foo is None

如果您要对垃圾收集进行自省或处理,或者检查自定义构建的字符串实习小工具是否正常工作,则可能有一个用例foo是is bar

True和False也是(现在)单例,但是没有用例,foo == True也没有用例foo is True

As John Feminella said, most of the time you will use == and != because your objective is to compare values. I’d just like to categorise what you would do the rest of the time:

There is one and only one instance of NoneType i.e. None is a singleton. Consequently foo == None and foo is None mean the same. However the is test is faster and the Pythonic convention is to use foo is None.

If you are doing some introspection or mucking about with garbage collection or checking whether your custom-built string interning gadget is working or suchlike, then you probably have a use-case for foo is bar.

True and False are also (now) singletons, but there is no use-case for foo == True and no use case for foo is True.


回答 11

他们中的大多数人已经回答了这一点。正如补充说明(基于我的理解和实验,但不是来自书面记录)的声明

==如果变量引用的对象相等

从上面的答案应该理解为

==如果变量引用的对象相等并且属于相同类型/类的对象

。我根据以下测试得出了这个结论:

list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)

这里的列表和元组的内容相同,但类型/类不同。

Most of them already answered to the point. Just as an additional note (based on my understanding and experimenting but not from a documented source), the statement

== if the objects referred to by the variables are equal

from above answers should be read as

== if the objects referred to by the variables are equal and objects belonging to the same type/class

. I arrived at this conclusion based on the below test:

list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)

Here the contents of the list and tuple are same but the type/class are different.


回答 12

is和equals(==)之间的Python区别

is运算符可能看起来与相等运算符相同,但它们并不相同。

is检查两个变量是否指向同一对象,而==符号检查两个变量的值是否相同。

因此,如果is运算符返回True,则相等性肯定为True,但相反的情况可能为True,也可能不是True。

这是一个演示相似性和差异性的示例。

>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
Tip: Avoid using is operator for immutable types such as strings and numbers, the result is unpredictable.

Python difference between is and equals(==)

The is operator may seem like the same as the equality operator but they are not same.

The is checks if both the variables point to the same object whereas the == sign checks if the values for the two variables are the same.

So if the is operator returns True then the equality is definitely True, but the opposite may or may not be True.

Here is an example to demonstrate the similarity and the difference.

>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
Tip: Avoid using is operator for immutable types such as strings and numbers, the result is unpredictable.

回答 13

当这篇文章中的其他人详细回答了这个问题时,我将主要强调字符串之间的比较is以及可以给出不同结果的== 字符串,我敦促程序员谨慎使用它们。

为了进行字符串比较,请确保使用==代替is

str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')

出:

str is hello
str == hello

在下面的例子中==,并is会得到不同的结果:

str = 'hello sam'
    if (str is 'hello sam'):
        print ('str is hello sam')
    if (str == 'hello sam'):
        print ('str == hello sam')

出:

str == hello sam

结论:

is谨慎使用以比较字符串

As the other people in this post answer the question in details, I would emphasize mainly the comparison between is and == for strings which can give different results and I would urge programmers to carefully use them.

For string comparison, make sure to use == instead of is:

str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')

Out:

str is hello
str == hello

But in the below example == and is will get different results:

str = 'hello sam'
    if (str is 'hello sam'):
        print ('str is hello sam')
    if (str == 'hello sam'):
        print ('str == hello sam')

Out:

str == hello sam

Conclusion:

Use is carefully to compare between strings