Introduction
Python has a lot of magic methods that can be really confusing sometimes.
We often do not realize the real need for a particular method, or we don't know how to apply it in the real world.
In this post, I'll explain a real use of one of them, the infamous __call__
.
Abstract Class
The Python language has abstract class support
Callabe, which helps us to create a class compatible with the Callable protocol, creating a class that inherits from Callable helps us in the correct implementation of the same.
To use this abstract class, you only need to import it from the abc library: from collections.abc import Callabe
and inherit it in your own class.
usage
Let's use an example, using a Mapper directly from an ORM (in this case, [SQLAlchemy()]), for a domain object, or class. That is, we will transform the ORM fields into a Python object without any coupling or external dependencies.
Callable Class:
from .dog_domain import Dog
from collections.abc import Callable
class DogMapper(Callable):
@staticmethod
def to_domain(dog):
return Dog(name=dog.name, legs=dog.legs, color=dog.color,) if dog else None
def __call__(self, dog):
return self.to_domain(dog)
ORM Class:
from app import db
from .dog_mapper import DogMapper
class Dog(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100))
legs = db.Column(db.Integer)
color = db.Column(db.Integer)
@property
def mapper(self):
return DogMapper()(self)
Domain Class:
class Dog:
def __init__(self, name, legs, color):
self.name = name
self.legs = legs
self.color = color
@clasmethod
def create(cls, name, color, legs=4):
return cls(name, color, legs,)
Explanation
In this case, we use the mapper property to initialize the mapper, and the conversion to the domain object automatically. This facilitates enough if we had to get some class by id, then import the Mapper and then perform the conversion in the end.
Done this way, callable is only used on demand, and when necessary. Thus, we do not carry out the conversion without a real need.
That way, we can use the mapper directly from the model, right after, such as:
dog = Dog.query.get(id=15).mapper
Conclusion
In this post I tried to demonstrate a real use of a Callable class, I hope that has helped!
If you have any questions or suggestions, don't hesitate to comment. 😉
See ya!
Top comments (0)