Why does id({}) == id({}) and id([]) == id([]) in CPython?

后端 未结 3 2113
北荒
北荒 2020-11-22 06:03

Why does CPython (no clue about other Python implementations) have the following behavior?

tuple1 = ()
tuple2 = ()                                                    


        
相关标签:
3条回答
  • 2020-11-22 06:26

    When you call id({}), Python creates a dict and passes it to the id function. The id function takes its id (its memory location), and throws away the dict. The dict is destroyed. When you do it twice in quick succession (without any other dicts being created in the mean time), the dict Python creates the second time happens to use the same block of memory as the first time. (CPython's memory allocator makes that a lot more likely than it sounds.) Since (in CPython) id uses the memory location as the object id, the id of the two objects is the same. This obviously doesn't happen if you assign the dict to a variable and then get its id(), because the dicts are alive at the same time, so their id has to be different.

    Mutability does not directly come into play, but code objects caching tuples and strings do. In the same code object (function or class body or module body) the same literals (integers, strings and certain tuples) will be re-used. Mutable objects can never be re-used, they're always created at runtime.

    In short, an object's id is only unique for the lifetime of the object. After the object is destroyed, or before it is created, something else can have the same id.

    0 讨论(0)
  • 2020-11-22 06:28

    The == operator on lists and dicts do not compare the object IDs to see if they the same object - use obj1 is obj2 for that.

    Instead the == operator compares the members of the list of dict to see if they are the same.

    0 讨论(0)
  • 2020-11-22 06:30

    CPython is garbage collecting objects as soon as they go out of scope, so the second [] is created after the first [] is collected. So, most of the time it ends up in the same memory location.

    This shows what's happening very clearly (the output is likely to be different in other implementations of Python):

    class A(object):
        def __init__(self): print "a",
        def __del__(self): print "b",
    
    # a a b b False
    print A() is A()
    # a b a b True
    print id(A()) == id(A())
    
    0 讨论(0)
提交回复
热议问题