I am working in Python (using the requests module) with an API communicating via JSON data structures. I could build my project on a web server using Javascript but I simply prefer to use Python at the moment.
The API is well documented and when I send a GET request I know exactly the shape of the response I’m going to receive. In order to better work with this received data, I’m creating class objects for each necessary schema so I can associate class methods/attributes to the given response I receive from the API.
What I found, as a way of tightening up my code and saving myself some time, is that I can create a class object, declare its attributes, and use the following code to set those attributes; so long as my attribute names match the expected keys in the JSON data object:
def __init__(self, json: json) -> None:
keys = self.__annotations__.keys()
for key in keys:
self.__setattr__(key, json[key])
This allows me to simply accept the JSON data object into the class initialization method and set the corresponding attributes.
Now for my question. Each schema has the exact same initialization method; the one above. They only have different attributes that match the given keys in the JSON objects.
So I have this kind of class structure as an example:
class ClassExample1:
attribute1: float
attribute2: float
attribute3: str
def __init__(self, json: json) -> None:
keys = self.__annotations__.keys()
for key in keys:
self.__setattr__(key, json[key])
class ClassExample2:
attribute1: bool
attribute2: list
def __init__(self, json: json) -> None:
keys = self.__annotations__.keys()
for key in keys:
self.__setattr__(key, json[key])
I’m wondering if there isn’t a better practice in which to structure my classes so that I’m not just copy/pasting the same code over and over again, whether that be inheritance or some other option I’m unaware of. I have several years of various types of development experience but unfortunately its been mostly in a position where I’m the sole developer for my company. I don’t have a lot of knowledge of "standard/best practices" and am constantly trying to educate myself in these topics while being outside of a standard corporate development environment. So when it comes to situations where I see myself using some redundant method, or using the same code blocks over and over, or what have you; it feels like I might be missing some other way of completing the task.
Thank you for you all who stayed for the whole post, and I appreciate any feedback anyone can offer me.
Cheers.
2
Answers
That is what inheritance is for.
Just create a base class with your
__init__
code (and maybe you could do__repr__
as well), and do the subclasses just declaring the attributes :Also, note that if your classes will expose all attributes in the JSON mapping as they are, you could use dataclasses, and expand your JSON key/values as kwargs with the
**
syntactic feature when instantiating then:If you need any other shared capability across your classes, those could be implemented as methods, and inheritance should beat the dataclass use – otherwise, the dataclass approach will also give you a free
__repl__
method, and other niceties (likedataclasses.asdict
when re-serializing your values)Assuming the json is a dict and that you don’t mind using the unpacking operator, I would use data classes, then you don’t have any code to duplicate: