IS and ID usage analysis in python

Source: Internet
Author: User
The examples in this article describe the IS and ID usages 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, 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 is proof.

Copy the 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 the 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 is false, but the ID is true, which is inconsistent with the facts we know, how to explain this phenomenon? The best solution to this situation is to call the DIS module to see what the two comparison statements have done.
Copy the 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
Slice+2
Delete_subscr
Delete_subscr
Slice+2
10340 Build_map
print_expr
11887 Jump_if_false_or_pop
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
print_expr
11887 Jump_if_false_or_pop
Delete_global 29281 (29281)


The real situation is when executing the. operator when the actual is generated a proxy object, Foo.bar is Foo.bar time, two object order generation, placed in the stack compared, because the address is different is certainly false, but the ID (foo.bar) = = ID (foo.bar) The time is different, first generate Foo.bar, and then calculate the address of foo.bar, after calculating the foo.bar address, there is no object to Foo.bar, so the Foo.bar object will be released. The Foo.bar object is then generated, because the memory size used by Foo.bar and Foo.bar is the same, so the memory address of the original foo.bar is reused, so the result of the ID (foo.bar) = = ID (foo.bar) is true.

The following content is provided by mail Leo Jay Daniel, who explains the more transparent.

It is problematic to use the ID (expression a) = = ID (expression b) to determine that the result of two expressions is not the same object.

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 Method object. According to the documentation:

When an instance attribute was referenced that isn ' t a data attribute,
It class is searched. If the name denotes a valid class attribute
That's a function object, a method object is 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 result, is a method object, in the ID (foo.bar) Such an expression, method object is only a temporary intermediate variable, do not have the meaning of the temporary intermediate variable ID.

A more obvious example is that
Copy the Code code as follows:

Print ID (foo.bar) = = ID (foo.__init__)

The result of the output is also true

Look at the ID of the document:

Return the "Identity" of an object. An integer (or long
Integer) which is guaranteed to being unique and constant for the This object
During its lifetime. 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, you can compare two objects with an ID. So, if you have to be more than that, you have to write:
Copy the 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 get the right result, entirely because the CPython implementation details are now determined. The current is implementation, is the left and right sides of the object are calculated, and then compare the two objects are the same address. In case one day change to, first count left, save the address, left off, then the right side, then compare, your is the result may be wrong. The issue is also mentioned in the official documentation. I think the right way is also like ID, first the left and right sides are computed, and explicitly bound to their names, and then use is to judge.

Hopefully this article will help you with Python programming.

  • Related Article

    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.