Sometimes you need to write a Python class that provides multiple ways to construct objects. In other words, you want a class that implements multiple constructors. This kind of class comes in handy when you need to create instances using different types or numbers of arguments. Having the tools to provide multiple constructors will help you write flexible classes that can adapt to changing needs.
In Python, there are several techniques and tools that you can use to construct classes, including simulating multiple constructors through optional arguments, customizing instance creation via class methods, and doing special dispatch with decorators. If you want to learn about these techniques and tools, then this tutorial is for you.
In this tutorial, you’ll learn how to:
Use optional arguments and type checking to simulate multiple constructors
Write multiple constructors using the built-in @classmethod decorator
Overload your class constructors using the @singledispatchmethod decorator
You’ll also get a peek under the hood at how Python internally constructs instances of a regular class and how some standard-library classes provide multiple constructors.
To get the most out of this tutorial, you should have basic knowledge of object-oriented programming and understand how to define class methods with @classmethod. You should also have experience working with decorators in Python.
Free Bonus: Click here to get access to a free Python OOP Cheat Sheet that points you to the best tutorials, videos, and books to learn more about Object-Oriented Programming with Python.
Python supports object-oriented programming with classes that are straightforward to create and use. Python classes offer powerful features that can help you write better software. Classes are like blueprints for objects, also known as instances. In the same way that you can build several houses from a single blueprint, you can build several instances from a class.
To define a class in Python, you need to use the class keyword followed by the class name:
>>> class Person:
… def __init__(self, name):
… self.name = name
Python has a rich set of special methods that you can use in your classes. Python implicitly calls special methods to automatically execute a wide variety of operations on instances. There are special methods to make your objects iterable, provide a suitable string representation for your objects, initialize instance attributes, and a lot more.
A pretty common special method is .__init__(). This method provides what’s known as the instance initializer in Python. This method’s job is to initialize instance attributes with appropriate values when you instantiate a given class.
In Person, the .__init__() method’s first argument is called self. This argument holds the current object or instance, which is passed implicitly in the method call. This argument is common to every instance method in Python. The second argument to .__init__() is called name and will hold the person’s name as a string.
Note: Using self to name the current object is a pretty strong convention in Python but not a requirement. However, using another name will raise some eyebrows among your fellow Python developers.
Once you’ve defined a class, you can start instantiating it. In other words, you can start creating objects of that class. To do this, you’ll use a familiar syntax. Just call the class using a pair of parentheses (()), which is the same syntax that you use to call any Python function:
>>> john = Person(“John Doe”)
In Python, the class name provides what other languages, such as C++ and Java, call the class constructor. Calling a class, like you did with Person, triggers Python’s class instantiation process, which internally runs in two steps:
Create a new instance of the target class.
Initialize the instance with suitable instance attribute values.
To continue with the above example, the value that you pass as an argument to Person is internally passed to .__init__() and then assigned to the instance attribute .name. This way, you initialize your person instance, john, with valid data, which you can confirm by accessing .name. Success! John Doe is indeed his name.
Note: When you call the class to create a new instance, you need to provide as many arguments as .__init__() requires so that this method can initialize all the instance attributes that demand an initial value.
Now that you understand the object initialization mechanism, you’re ready to learn what Python does before it gets to this point in the instantiation process. It’s time to dig into another special method, called .__new__(). This method takes care of creating new instances in Python.
Note: The .__new__() special method is often called a class constructor in Python. However, its job is actually to create new objects from the class blueprint, so you can more accurately call it an instance creator or object creator.
The .__new__() special method takes the underlying class as its first argument and returns a new object. This object is typically an instance of the input class, but in some cases, it can be an instance of a different class.
If the object that .__new__() returns is an instance of the current class, then this instance is immediately passed to .__init__() for initialization purposes. These two steps run when you call the class.
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]