Curiously:
奇怪的是:
>>> a = 123
>>> b = 123
>>> a is b
True
>>> a = 123.
>>> b = 123.
>>> a is b
False
Seems a is b
being more or less defined as id(a) == id(b)
. It is easy to make bugs this way:
似乎a是b或多或少被定义为id(A)==id(B)。用这种方式制造错误很容易:
basename, ext = os.path.splitext(fname)
if ext is '.mp3':
# do something
else:
# do something else
Some fnames unexpectedly ended up in the else block. The fix is simple, we should use ext == '.mp3'
instead, but nonetheless if ext is '.mp3'
on the surface seems like a nice pythonic way to write this and it's more readable than the "correct" way.
有些名字出人意料地出现在Else块中。解决方法很简单,我们应该使用ext==‘.mp3’,但是如果ext表面上是‘.mp3’,似乎是一种很好的编写方法,而且比“正确”的方法更具可读性。
Since strings are immutable, what are the technical details of why it's wrong? When is an identity check better, and when is an equality check better?
既然字符串是不变的,那么它为什么是错误的技术细节是什么呢?什么时候身份检查更好,什么时候平等检查更好?
更多回答
They are fundamentally different.
它们从根本上是不同的。
==
compares by calling the __eq__
method
is
returns true if and only if the two references are to the same object
So in comparision with say Java:
与Java相比:
is
is the same as ==
for objects
==
is the same as equals
for objects
As far as I can tell, is
checks for object identity equivalence. As there's no compulsory "string interning", two strings that just happen to have the same characters in sequence are, typically, not the same string object.
据我所知,是检查对象身份的等价性。因为没有强制的“字符串内嵌”,所以恰好在序列中有相同字符的两个字符串通常不是相同的字符串对象。
When you extract a substring from a string (or, really, any subsequence from a sequence), you will end up with two different objects, containing the same value(s).
当您从一个字符串(或者,实际上是一个序列中的任何子序列)中提取一个子字符串时,您将得到两个不同的对象,它们包含相同的值(S)。
So, use is
when and only when you are comparing object identities. Use ==
when comparing values.
因此,当且仅当您比较对象身份时才使用。在比较值时使用==。
Simple rule for determining if to use is or == in Python
在Python中确定是使用is还是==的简单规则
Here is an easy rule (unless you want to go to theory in Python interpreter or building frameworks doing funny things with Python objects):
这里有一条简单的规则(除非您想要学习有关Python解释器的理论知识,或者使用Python对象构建框架来做一些有趣的事情):
Use is only for None
comparison.
使用仅用于不进行比较。
if foo is None
Otherwise use ==.
否则,请使用==。
if x == 3
Then you are on the safe side. The rationale for this is already explained int the above comments. Don't use is if you are not 100% sure why to do it.
那么你就是安全的一方。这样做的理由已经在上述评论中解释过了。如果你不能100%确定为什么要这么做,就不要使用。
It would be also useful to define a class like this to be used as the default value for constants used in your API. In this case, it would be more correct to use is than the == operator.
定义一个这样的类作为API中使用的常量的缺省值也很有用。在这种情况下,使用is比使用==运算符更正确。
class Sentinel(object):
"""A constant object that does not change even when copied."""
def __deepcopy__(self, memo):
# Always return the same object because this is essentially a constant.
return self
def __copy__(self):
# called via copy.copy(x)
return self
You should be warned by PyCharm when you use is
with a literal with a warning such as SyntaxWarning: "is" with a literal. Did you mean "=="?
. So, when comparing with a literal, always use ==
. Otherwise, you may prefer using is
in order to compare objects through their references.
当您将is与带有警告的文本一起使用时,您应该得到PyCharm的警告,例如,将语法警告:“is”与文本一起使用。你是说“==”吗?因此,在与文字进行比较时,请始终使用==。否则,您可能更喜欢使用is,以便通过引用比较对象。
更多回答
Actually, there is string interning. It just won't happen for dynamically created strings.
实际上,有串串实习。这不会发生在动态创建的字符串中。
@katrielalex there is a builtin intern()
which lets you explicitly intern dynamically created strings; it just doesn't happen by itself.
@ktrielalex有一个内置的intern(),它允许您显式地实例化动态创建的字符串;只是它不会自己发生。
@katriealex: I think I actually meant "automatic and compulsory string-interning" (there are, I believe, some languages that do do that).
@kailelex:我想我实际上是指“自动和强制的字符串实习”(我相信,有些语言确实这样做了)。
@Duncan: I think the compiler automagically interns string literals that appear in the source, though. And @Vatine: ugh :p
@Duncan:不过,我认为编译器会自动实例化源代码中出现的字符串。和@Vatine:ugh:p
@katrielalex The compiler automatically interns strings in the source if the content of the string could be a valid Python identifier. Other strings are not interned, but duplicate strings in a single compilation unit will still be shared (but not shared with other compilation units). All of which is of course an implementation detail and subject to change at any time.
@ktrielalex如果字符串的内容可以是有效的Python标识符,则编译器会自动在源代码中实例化字符串。其他字符串不会被占用,但单个编译单元中的重复字符串仍将被共享(但不与其他编译单元共享)。当然,所有这些都是实现细节,随时可能发生变化。
They Python way is readable code, meaning use ==
as long as that's what you mean (almost always). is None
if x:
if not x:
is Python convention to check for None True False
respectively. Real use of is
comes when you examine complex data structures, e.g. assert not [l for l in mylist if l is mylist]
a simple check against cycles in (plain) data structure.
它们是可读的代码,这意味着只要您是这个意思(几乎总是如此),就使用==。如果x:If Not x:是分别检查None True False的Python约定,则为None。IS的真正用法是在检查复杂数据结构时出现的,例如,断言Not[L在我的列表中为L,如果L是我的列表]对(纯)数据结构中的循环进行简单的检查。
what about types? type("foo") is str
is probably ok
那类型呢?类型(“foo”)是字符串可能没有问题
types are checked using isinstance
, e.q. isinstance("foo", str)
, or, if you want to exclude subclasses, type("foo") == str
is enough.
使用isinstance检查类型,例如isinstance(“foo”,str),或者,如果你想排除子类,type(“foo”)== str就足够了。
我是一名优秀的程序员,十分优秀!