Class factory and dataclass in python
- Introduction
- The problem
- Solution using a class factory
- Solution using data class
- Conclusion
- References
Introduction
This post continues with using a class factory in python, a powerful idiom that I have seen discussed often. I extensively used this idiom in previous blogs about policy-based design in python.
In this blog, I will show how to use a class factory to create a new style for defining classes in python. This style is more conducent to express types when decomposing a problem using object-oriented approaches1 typically found in typed strongly-typed language2.
The problem
Let say that you have a problem that requires a simple Author type with a name and desc (short for description) fields. Naively, I can do this using the following python code:
Note: In the previous example, I am using type hints3, a relatively recent addition to python4. Python documentation is a good source on how to use these hints5.
My issue with this example is the following: I need to use the class constructor to define the object data’s basic structure. Using type hints, now it is possible to declare the intended type for each of the fields. However, this definition comes as type hints for the constructor arguments rather than the actual object fields.
Things become more complicated if you want to enforce some protection to the field values. It is common in some object-oriented approaches that field values should be those provided during the object instantiation. In the previous example, the code user can edit field values at any time. One way to freeze the field values is to define them as the class’s property without a ‘setter’ or ‘delattr’ function associated with it.
In this example, any attempt to redefine a field’s value after instantiation will raise AttributeError exception. This solution works at the cost of having a somewhat convoluted syntax to define just an elementary class6.
Solution using a class factory
Using a class factory I call CreateClass you can write previous two examples using the following notation:
or for frozen field version
The code class factory is the following:
Note: ClassFactory.py shows a full working example of the code.
Still, I am not very happy with the solution because of the following reasons:
- Syntax is very different from the traditional one using the class keyword.
- Type hints are not supported in this example.
- The fact I have to write a custom made factory.
Likely for me, python developers were listening to my prayers and created python data classes.
Solution using data class
Data classes are a relatively recent addition to python three define in PEP-5577. I will not discuss all the features that are part of the data classes. You can read about it at your own leisure8. Instead, I will show how to implement my simple examples using the @dataclass class decorator.
In the first example, I can write it as follow.
and the second example using frozen fields
Note: PythonDataclass.py shows a full working example of the code.
Conclusion
I use a class factory in an attempt to improve python syntax to define classes with fields. However, in the process, I learn about python data classes. As far as I can read in the code, python data classes use a class decorator to decorate a user-defined class with fields. It is a beautiful solution to speed up the development of code with a strong object-oriented flavor.
References
-
You can see as an example of this approach the excellent educative course Grokking the Object-Oriented Design Interview. ↩
-
Magic lies here - Statically vs Dynamically Typed Languages. ↩
-
Imaging doing this in a technical interview on a whiteboard. How many silly syntax mistakes can occur you can make that would like rather bad for you. ↩
-
The Ultimate Guide to Data Classes in Python 3.7 or dataclasses — Data Classes. ↩
Note of a interdiciplinarian by Victor E. Bazterra is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.