Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does Python Create a New Object

Tags:

python

Python uses names to reference objects. When we say a = b, a and b now refer to the same object, and if we change a, we will see the same change in b. For example:

a = [1, 2, 3]
b = a

a.append(4)

print(b)

will print [1, 2, 3, 4].

However, some operations do create new objects. For example:

a = 1
b = a

a = a + 1

print(b)

will print 1. Clearly the line a = a + 1 somehow creates a new object with a value of a + 1 and binds the name a to it. How does this work? What is the mechanism that creates a new object in this case?

This question is not a duplicate of this one, as I am asking specifically how the object creation happens in this case, whereas the other question was more generally about when names share objects.

like image 894
PProteus Avatar asked Sep 11 '25 12:09

PProteus


1 Answers

I found the information I was looking for on the mechanics of object creation in Luciano Ramalho's book Fluent Python.

Ramalho explains that while __init__ is usually considered the "constructor", in fact, objects are created by calling the __new__ method. It is a class method, and it returns an instance of a class, which gets passed to __init__ as the first argument (conventionally "self"). Thus, __init__ is the initializer, not the constructor.

This can be illustrated with the following example:

class C(object):
    def __new__(cls):
        new_inst = object.__new__(cls)
        print new_inst.__dict__
        new_inst.var_1 = 1
        return new_inst

    def __init__(self):
        print self.__dict__
        self.var_2 = 2

a = C()             # Prints:
                        # {}
                        # {'var_1': 1}
print a.__dict__    # returns {'var_2': 2, 'var_1': 1}

b = C.__new__(C)    # Prints:
                        # {}
print b.__dict__    # returns {'var_1': 1}

b.__init__()        # Prints:
                        # {'var_2': 2, 'var_1': 1}
print b.__dict__    # returns {'var_2': 2, 'var_1': 1}

The line a = C() calls __new__ followed by __init__, as we can see from the printouts of __dict__. This can be broken into separate calls, as shown with the object b.

This question is also relevant.

like image 107
PProteus Avatar answered Sep 14 '25 03:09

PProteus