Search code examples
pythonvariable-assignmentpython-internals

When python creates new objects in memory


In the following example Python uses the same integer object in the memory for all three names x, y and z in the namespace

def main():
    x = 0
    y = 0
    z = 0
    print(x,y,z)
    print(x is y is z)
    y = 2
    print(x,y,z)
    print(x is y)
    print(z is y)
    print(x is z)

if __name__ == "__main__":main()

Output:

0 0 0
True
0 2 0
False
False
True

Why Python doesn't use the same tuple object here ( yes it is the choice of language designers but why) and a better questin to ask is when python creates new objects in memory

def main():
    a = 1, 2, 3
    b = (1, 2, 3)
    c = 1, 2, 3

    print(type(a) == type(b))
    print(a == b)
    print(a is b)
    print(a == c)
    print(a is c)

if __name__ == "__main__":main()

Output:

True
True
False
True
False

Solution

  • For a literal that represents a mutable object, every evaluation of the literal must generate a new object.

    For a literal that represents an immutable object, whether a new object is created comes down to arbitrary implementation details. It could have chosen to use the same tuple. It could use the same tuple in a future release, or in a different Python implementation. Your example actually does reuse tuples if you call main repeatedly, but different tuples for a, b, and c. You shouldn't rely on it being one way or another.

    If you want to see the particular implementation details for this case, the CPython bytecode compiler ordinarily merges equivalent constants together in a code object (the mechanism involves a dict, with some extra work to keep things like 1.0 and 1 from merging), but the peephole optimization pass that precomputes the 3 tuples occurs in a postprocessing phase that doesn't have the deduplication machinery in place.