python class constructors class constructors are a fundamental part of object oriented programming they allow you to create and properly initialize objects of a given class making those objects ready to use class constructors internally trigger python's instantiation process which runs through two main steps instance creation and instance initialization if you want to dive deeper into how python internally constructs objects and learn how to customize the process then this course is for you in this course you'll learn how to understand python's internal instantiation process how to customize object initialization using init and how to fine tune object creation by overriding new with this knowledge you'll be able to tweak the creation and initialization of objects in your custom python classes this will give you control over the instantiation process at a more advanced level to better understand the examples and concepts in this course you should have some knowledge of object-oriented programming and special methods in python if you need to get up to speed with object orientated programming then real python has you covered with this course now that you know what's going to be covered in this course let's get started the instantiation process like many other programming languages python supports object-oriented programming at the heart of python's object-oriented capabilities you'll find the class keyword which allows you to define custom classes that can have attributes for storing data and methods for providing behavior once you have a class to work with then you can start creating new instances or objects of that class which is an efficient way to reuse functionality in your code creating and initializing objects of a given class is a fundamental step in object-oriented programming this step is often referred to as object construction or instantiation the tool responsible for running this instantiation process is commonly known as a class constructor in python to construct an object of a given class you just need to call the class with appropriate arguments as you would call any function in this course you'll see examples run using the b python repl it offers a number of improvements over the standard python repel including colour coding all of the examples seen here will run in the python repo which you'll usually access by typing python at the command prompt in this example you define some class using the class keyword this class is currently empty because it doesn't have any attributes or methods instead the classes body only contains a pass statement as a placeholder statement that does nothing then you create a new instance of some class by calling the class with a pair of parentheses in this example you don't need to pass any arguments in the call because your class doesn't take any arguments yet in python when you call a class such as seen in this example you're calling the class constructor which creates initialize and returns a new object by triggering python's internal instantiation process a final point to note is that calling a class isn't the same as calling an instance of a class these are two different and unrelated topics to make a classes instance callable you need to implement a call special method which has nothing to do with python's instantiation process you trigger python's instantiation process whenever you call a python class to create a new instance this process runs through two separate steps which you can describe as follows firstly create the new instance of the target class and secondly initialize the new instance with an appropriate initial state to run the first step python classes have a special method called new which is responsible for creating and returning a new empty object then another special method init takes the resulting object along with the class constructor's arguments the init method takes the new object as its first argument self then it sets any required instance attribute to a valid state using the arguments that the class constructor passed to it in the next section of the course you'll take a look at code which will explore the instantiation process in a practical example exploring the instantiation process to explore how python's instantiation process works internally consider the following example of a point class that implements custom versions of both the new and init special methods for demonstration purposes this line defines the point class using the class keyword followed by the class name this defines the new special method which takes the class as its first argument note that using cls as the name of this argument is a strong convention in python just like using self to name the current instances the method also takes args and kw args which allow for passing an undefined number of initialization arguments to the underlying instance this line prints a message when new runs the object creation step this complex looking line creates a new point instance by calling the parent classes new method with cls as an argument in this example object is the parent class and the call to super gives you access to it then the instance is returned this instance will be the first argument to init here you define init which is responsible for the initialization step this method takes a first argument called self which holds a reference to the current instance the method also takes two additional arguments x and y these arguments hold initial values for the instance attributes dot x and dot y you need to pass suitable values for these arguments to the call to point as you'll learn in a moment these lines print a message when init runs the object initialization step and then initialize the x and y attributes respectively to do this they use the provided input arguments x and y finally these lines implement the wrapper special method which provides a proper string representation for the point class with point in place you can uncover how the instantiation process works in practice save the code to a file called point.py and start a new python session from a command line window in the same directory as the code is saved then run the code seen on screen calling the point class constructor creates initialize and returns a new instance of the class this instance is then assigned to the variable point in this example the call to the constructor also lets you know the steps that python internally runs to construct the instance first python calls new and then init resulting in a new and fully initialized instance of point as you confirmed at the end of the example to continue learning about class instantiation in python you can try running both steps manually here you first call new on the point class passing the class itself as the first argument to the method this call only runs the first step of the instantiation process creating a new and empty object note that creating an instance this way bypasses the call to init and the object is not initialized this can be demonstrated by trying to access the x and y attributes which generate errors once you have the new object then you can initialize it by calling init with an appropriate set of arguments after this the point object is properly initialized with all of its attributes set up note that this code is intended to be a demonstration of how the instantiation process works internally it's not something that you would typically do in real code a subtle and important detail to note about the new special method is that it can also return an instance of a class different from the class that implements the method itself when that happens python doesn't call init in the current class because there's no way to unambiguously know how to initialize an object of a different class next you'll see an example of this on screen where the new method of the b-class returns an instance of the a-class because b new returns an instance of a different class python doesn't run b init to confirm this behavior save the code into a file called a b underscore classes dot py and then run the following code in an interactive python session the call to the b class constructor runs b new which returns an instance of a instead of b and this is why b init never runs note that b doesn't have a b value attribute in contrast b does have an a value attribute with a value of 42. his instance can be used to check if b is a member of a given class note that it is not a member of class b but it is a member of class a now that you know the steps that python takes internally to create instances of a given class you're ready to dig a little deeper into other characteristics of the init and new special methods and the steps that they run so in the next section you'll start that off by looking at init object initialization within it in python the init method is probably the most common special method you'll override in your custom classes almost all your classes will need a custom implementation of a knit to allow you to initialize your objects properly the purpose of this initialization step is to leave your new objects in a valid state so that you can start using them right away in your code in this section you'll learn the basics of writing your own init methods and how they can help you customize your classes the most bare-bones implementation of init that you can write will just take care of assigning input arguments to matching instance attributes for example let's say you're writing a rectangle class that requires width and height attributes in that case you'd create code similar to what's seen on screen as you've already learned init runs the second step of the object instantiation process in python its first argument self holds the new instance that results from calling new the rest of the arguments to init are normally used to initialize instance attributes here you initialize the rectangle's width and height attributes using the width and height arguments to init it's important to note that without counting self the arguments to init are the same ones that you passed in the call to the class constructor so in a way the init signature defines the signature of the class constructor additionally keep in mind that init must not explicitly return anything other than none or you'll get a type error exception here the init method attempts to return an integer which ends up raising a type error exception at runtime the error message in this example says that init should return none however you don't need to return none explicitly because methods and functions without an explicit return statement return none implicitly in python with this implementation of init you ensure that width and height get initialized to a valid state when you call the class constructor with appropriate arguments that way your rectangles will be ready for use right after the construction process finishes in init you can also run any transformation over the input arguments to properly initialize the instance attributes for example if your users will use rectangle directly then you might want to validate the supplied width and height and make sure that they're correct before initializing the corresponding attributes in this updated implementation of init you make sure that the input width and height arguments are positive numbers before initializing the corresponding width and height attributes if either validation fails then you raise a value error as seen on screen a more pythonic technique to tackle attribute validation is to turn attributes into properties to learn more about properties check out this real python course now let's say that you're using inheritance to create a custom class hierarchy and reuse some functionality in your code if your subclasses provide an init method then this method must explicitly call the base classes init method with appropriate arguments to ensure the correct initialization of instances to do this you should use the built-in super function as seen on screen the first line in employees init method calls super init with the name and birth date as arguments this call ensures the initialization of name and birth date in the parent class person this technique allows you to extend the base class with new attributes and functionality here the position attribute is used only by the employee class and is part of the employee initialization function this is confirmed by viewing the attributes of the john object as seen on screen you should know that the base implementation of init comes from the built-in object class this implementation is automatically called when you don't provide an explicit init method in your classes you can make your object's initialization step flexible and versatile by tweaking the init special method to this end one of the most popular techniques is to use optional arguments this technique allows you to write classes in which the constructor accepts different sets of input arguments at instantiation time which arguments to use at a given time will depend on your specific needs and context as a quick example check out the following greeter class here init takes a regular argument called name it also takes an optional argument called formal which defaults to false because formal has a default value you can construct objects relying on this value or by providing your own the class's final behavior will depend on the value of formal if this argument is false then you'll get an informal greeting when you call greet otherwise you'll get a more formal greeting to try the greeter class out save the code into a file called greet.py then open a python session in the working directory and run the following code here you create an informal greeter object by passing a value to the name argument and relying on the default value of formal you get an informal greeting on your screen when you call greet on the informal greeter object in this example you use a name and a formal argument to instantiate greeter because formal is true the result of calling greet is a formal greeting even though this is a tour example it showcases how default argument values are a powerful python feature that you can use to write flexible initializers for your classes these initializers will allow you to instantiate your classes using different sets of arguments depending on your needs now that you know the basics of the init special method and the object initialization step it's time to change gears and start diving deeper into new and the object creation step