What is the is and id in Python?

Source: Internet
Author: User
(Ob1isob2) is equivalent to (id (ob1) id (ob2). First, the id function obtains the memory address of the object. if the memory addresses of the two objects are the same, then these two objects must be one object. Is equivalent to is. Python source code. (Ob1 is ob2) is equivalent to (id (ob1) = id (ob2 ))

First, the id function can obtain the object's memory address. if the two objects have the same memory address, the two objects must be one object. Is equivalent to is. Python source code.

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 how can this problem occur with the code below?

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.barOut[4]: FalseIn [5]: id(foo.bar) == id(Foo.bar)Out[5]: True

The two objects are judged to be False by "is" and True by id ", which is inconsistent with the known facts. how can we explain this phenomenon? The best solution to this problem is to call the dis module to see what the two comparison statements have done.

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)         10 STORE_SLICE+1           11 SLICE+2                 12 DELETE_SUBSCR           13 DELETE_SUBSCR           14 SLICE+2                 15 BUILD_MAP       10340         18 PRINT_EXPR              19 JUMP_IF_FALSE_OR_POP 11887         22 DELETE_GLOBAL   29281 (29281)         25 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         11 PRINT_EXPR              12 JUMP_IF_FALSE_OR_POP 11887         15 DELETE_GLOBAL   29281 (29281)

The actual situation is when execution. actually, a proxy object, foo. bar is Foo. when bar is used, the two objects are generated sequentially and put in the stack for comparison. because the addresses are different, it must be False, but id (foo. bar) = id (Foo. bar. bar, and then calculate foo. the address of bar. after calculation, foo. after the address of bar, no object points to foo. bar, so foo. the bar object will be released. Then generate Foo. bar object, because foo. bar and Foo. bar uses the same memory size, so it just re-uses the original foo. bar memory address, so id (foo. bar) = id (Foo. bar) is True.

The following content is provided by Leo Jay Daniel, who explained it more transparently.

It is a problem to use id (expression a) = id (expression B) to determine whether the results of two expressions are the same object.

Foo. bar is called attribute reference [1]. it is a type of expression. Foo is an instance object and bar is a method. in this case, the result returned by the expression foo. bar is method object [2]. According to the document:

When an instance attribute is referenced that isn’t a data attribute, its class is searched. If the name denotes a valid class attribute that is a function object, a method object is created by packing (pointers to) the instance object and the function object just found together in an abstract object: this is the method object.

Foo. bar itself is not a simple name, but the calculation result of the expression. it is a method object in id (foo. bar) in such an expression, method object is just a temporary intermediate variable, and it makes no sense to do id for the temporary intermediate variable.

A more obvious example is,

print id(foo.bar) == id(foo.__init__)

The output result is also True.

See id document [3]:

Return the “identity” of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value. CPython implementation detail: This is the address of the object in memory.

Only when you can ensure that the object will not be destroyed can you use IDs to compare two objects. Therefore, if you have to compare it, you have to write it like this:

fb = foo.bar Fb = Foo.bar print id(fb) == id(Fb)

That is, bind the results of the two expressions to the name, and then compare whether the results are the same object to get the correct results.

The is expression [4] is the same. you get the correct result because CPython's current implementation details are determined. The current implementation of is to calculate the objects on both sides of the left and right, and then compare whether the addresses of these two objects are the same. If you change it to another day, first calculate the left side, save the address, release the left side, and then calculate the right side. then, if you compare it, your is result may be wrong. This issue is also mentioned in the official document [5]. In my opinion, the correct method is also like id. First, calculate both the left and right sides, explicitly bind them to their respective names, and then use is to judge.

[1] http://docs.python.org/2/reference/expressions.html#attribute-references
[2] http://docs.python.org/2/tutorial/classes.html#method-objects
[3] http://docs.python.org/2/library/functions.html#id
[4] http://docs.python.org/2/reference/expressions.html#index-68
[5] http://docs.python.org/2/reference/expressions.html#id26

The above is the details about the is and id in Python. For more information, see other related articles in the first PHP community!

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.