IS and ID usage analysis in Python _python

Source: Internet
Author: User
Tags in python

The examples in this article describe the IS and ID usage in Python. Share to everyone for your reference. The specific analysis is as follows:

(Ob1 is OB2) equivalent to (ID (ob1) = = ID (ob2))

First the ID function can get the memory address of the object, and if the memory address of the two objects is the same, then the two objects must be an object. is equivalent to IS. Python source code as proof.

Copy Code code as follows:
Static Pyobject *
Cmp_outcome (int op, register pyobject *v, register Pyobject *w)
{
int res = 0;
Switch (OP) {
Case PYCMP_IS:
res = (v = = W);
Break
Case Pycmp_is_not:
res = (v!= w);
Break

But look at the code below, how does this happen?

Copy Code code as follows:
In [1]: Def bar (self, x):
...: return self.x + y
...:

In [2]: Class Foo (object):
..: x = 9
...: def __init__ (self, x):
...: self.x = x
...: bar = bar
...:

In [3]: foo = foo (5)

In [4]: Foo.bar is Foo.bar
OUT[4]: False

In [5]: id (foo.bar) = = ID (foo.bar)
OUT[5]: True

Two objects are judged by the is false, with the ID is true, which is inconsistent with the facts we know, how to explain this phenomenon? The best way to solve this situation is to call the DIS module to see what the two comparison statements do.

Copy Code code as follows:
In [7]: Dis.dis ("id (foo.bar) = = ID (foo.bar)")
0 Build_map 10340
3 Build_tuple 28527
6 <46>
7 Delete_global 29281 (29281)
Ten store_slice+1
One slice+2
Delete_subscr
Delete_subscr
Slice+2
Build_map 10340
print_expr
Jump_if_false_or_pop 11887
Delete_global 29281 (29281)
Store_slice+1

In [8]: Dis.dis ("Foo.bar is Foo.bar")
0 Build_tuple 28527
3 <46>
4 Delete_global 29281 (29281)
7 slice+2
8 Build_map 8307
One print_expr
Jump_if_false_or_pop 11887
Delete_global 29281 (29281)

The real situation is when the. operator is actually generated a proxy object, when the Foo.bar is Foo.bar, two objects are generated sequentially, placed on the stack compared, because the address difference is definitely false, but ID (foo.bar) = = ID (foo.bar) The time is different, first generate Foo.bar, and then calculate the Foo.bar address, after calculating Foo.bar address, no object points to Foo.bar, so the Foo.bar object will be released. The Foo.bar object is then generated, and because the memory size of the Foo.bar and Foo.bar is the same, the memory address of the original foo.bar is reused, so the result of ID (foo.bar) = = ID (foo.bar) is true.

The following content is provided by the Mail, Leo Jay, who is more transparent in his explanation.

The idea of using ID (expression a) = = ID (expression b) to determine whether the result of two expressions is not the same object is problematic.

Foo.bar This form is called attribute reference [1], which is one of the expressions. Foo is a instance Object,bar is a method, and this time the expression foo.bar returns the result called object. According to the documentation:

When the instance attribute is referenced that isn ' t a data attribute,
Its class is searched. If the name denotes a valid class attribute
This is a function object, the A method object are created by packing
(pointers to) The instance object and the function object just found
Together in a abstract Object:this is the method object.

Foo.bar itself is not a simple name, but the expression of the calculation, is a method object, in an expression such as ID (Foo.bar), method object is only a temporary intermediate variable, the temporary intermediate variable ID is meaningless.

A more obvious example is that

Copy Code code as follows:
Print ID (foo.bar) = = ID (foo.__init__)

The result of the output is also true

Look at the ID document:

Return the ' identity ' of an object. This is an integer (or long
Integer) which is guaranteed to being unique and constant for this object
During its lifetime. Two objects with non-overlapping lifetimes
Have the same ID () value.
CPython implementation Detail:this is the "address" of the object in memory.

Only if you can guarantee that the object will not be destroyed, can you use ID to compare two objects. So, if you have to be more than that, you have to write:

Copy Code code as follows:
FB = Foo.bar
Fb = Foo.bar
Print ID (FB) = = ID (FB)

You can get the correct result by binding the result of two expressions to the name and then to the same object.

The IS expression is the same, and you now have the correct result, entirely because of the cpython of the present implementation details. Now the implementation of IS, the left and right sides of the object are calculated, and then compare the addresses of the two objects are the same. In the event of a change of day, the left side, save the address, the left release, and then to the right, and then compare, your is may be the result of the wrong. The issue is also mentioned in the official document. I think the correct approach is also like ID, first the left and right sides are calculated, and explicitly bound to their names, and then use is to judge.

I hope this article will help you with your Python programming.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.