0

So I'm learning that instance objects have bound methods but you may also call the function by accessing the class because a function can be an attribute of said class.

My question would then be, how does python pass in self into the __init__ method automatically when no self has been created? Is there some behind the scenes process that I'm not familiar with? It seems like a chicken before the egg kind of thing.

I know that other function calls do require you to pass the instantiated object but init seems pretty mysterious to me.

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
JamesMat
  • 7
  • 2
  • 1
    _"Is there some behind the scenes process that I'm not familiar with?"_ - Yup. Python simply uses the `__init__` method to _customize_ a class. The actual creation of the class object happens before the call to `__init__`. The `__new__` method does the real work of creating the class instance. See the question [_Why is __init__() always called after __new__()?_](https://stackoverflow.com/questions/674304/why-is-init-always-called-after-new) – Christian Dean Jun 15 '18 at 04:33

1 Answers1

1

My question would then be, how does python pass in self into the init method automatically when no self has been created? Is there some behind the scenes process that I'm not familiar with? It seems like a chicken before the egg kind of thing.

Yes, you are correct. The __init__ is called after a class instance has been created. __init__ does not create a class instance, it simply allows one to 'customize' the instance. The __new__ is the method that is actually used to create new class instances. It takes in a reference to a class object, and any arguments passed to said class object.

Here is the documentation for the __init__ and __new__ methods:

__init__:

Called after the instance has been created (by __new__()), but before it is returned to the caller. The arguments are those passed to the class constructor expression. If a base class has an __init__() method, the derived class’s __init__() method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance; for example: super().__init__([args...]).

Because __new__() and __init__() work together in constructing objects (__new__() to create it, and __init__() to customize it), no non-None value may be returned by __init__(); doing so will cause a TypeError to be raised at runtime.

__new__:

Called to create a new instance of class cls. __new__() is a static method (special-cased so you need not declare it as such) that takes the class of which an instance was requested as its first argument. The remaining arguments are those passed to the object constructor expression (the call to the class). The return value of __new__() should be the new object instance (usually an instance of cls).

Typical implementations create a new instance of the class by invoking the superclass’s __new__() method using super().__new__(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning it.

If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__().

If __new__() does not return an instance of cls, then the new instance’s __init__() method will not be invoked.

Community
  • 1
  • 1
Christian Dean
  • 22,138
  • 7
  • 54
  • 87