Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
365 views
in Technique[技术] by (71.8m points)

reference - Types for which "is" keyword may be equivalent to equality operator in Python

For some types in Python, the is operator seems to be equivalent to the == operator. For example:

>>> 1 is 1
True
>>> "a spoon" is "a spoon"
True
>>> (1 == 1) is (2 == 2)
True

However, this is not always the case:

>>> [] == []
True
>>> [] is []
False

This makes sense for mutable types such as lists. However, immutable types such as tuples seem to display the same behavior:

>>> (1, 2) == (1, 2)
True
>>> (1, 2) is (1, 2)
False

This raises several questions:

  1. Is the == / is equivalence related to immutability?
  2. Are the behaviors above specified, or an implementation detail?
  3. Most importantly (and basically), how can I know if an assignment will result in a copy of an object being made, or a reference to it being made?

Update: If assignment is always by reference, why doesn't the following print 2?:

>>> a = 1
>>> b = a
>>> a = 2
>>> b
1

Why isn't this equivalent to the following C snippet:

int a = 1;
int *b = &a;
a = 2;
printf("%d
", *b);

Apologies for the newbness of this question, but I am a Python novice and feel that it is important to understand this. Is there any reading you would recommend to understand these sort of issues?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The is operator tests if two objects are physically the same, that means if they have the same address in memory. This can also be tested using the id() function:

>>> a = 1
>>> b = 1
>>> a is b
True
>>> id(a) == id(b)
True

The == operator on the other hand, tests for semantical equality. This can also be overridden by custom classes by implementing the __eq__() function. Semantically, two different lists are equal if their elements are all equal, but physically they will be different objects.

Immutable types like strings and tuples might be pooled by the Python implementation, so that two literal string objects are in fact physically identical. But this does not mean that you can always use is to compare those types, as demonstrated in the following example:

>>> "foobar" is "foobar"   # The interpreter knows that the string literals are
True                       # equal and creates only one shared object.
>>> a = "foobar"
>>> b = "foobar"
>>> a is b        # "foobar" comes from the pool, so it is still the same object.
True
>>> b = "foo"     # Here, we construct another string "foobar" dynamically that is
>>> b += "bar"    # physically not the same as the pooled "foobar".
>>> a == b
True
>>> a is b
False

Assignments in Python always bind the reference to an object to a variable name and never implies a copy.

UPDATE

Analogous to C, think of Python variables always being pointers:

>>> a = 1
>>> b = a
>>> a = 2
>>> b
1

Roughly equivalent to:

const int ONE = 1;
const int TWO = 2;

int *a = &ONE;
int *b = a;  /* b points to 1 */
a = &TWO;    /* a points to 2, b still points to 1 */

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...