You can achieve this using kwargs and __ getattribute __ method
EDIT:
A more readable & efficient approach:
from dataclasses import dataclass
from functools import reduce
@dataclass
class Q:
fruits = ('taste', 'color', 'shine')
vege = ('is_green', 'color', 'juiceable')
meat = ('is_white', 'is_dark', 'is_red', 'meat_name')
carbs = ('is_refined', 'gi')
@classmethod
def get_fields(cls, **kwargs):
fields = set()
for key, is_key_true in kwargs.items():
if is_key_true:
fields.update(getattr(cls, key.replace('add_', '')))
return ", ".join(sorted(fields))
print(f"SELECT {Q.get_fields(add_fruits=True, add_vege=True, add_meat=False)} from food_features")
This will output
SELECT color, is_green, juiceable, shine, taste from food_features
Old code & some explains:
Using kwargs you will receive a dictionary of function arguments, where you can put anything you want to add. For example add_fruits=True, add_vege=True, etc
. We will use that dictionary to map the arguments in a tuple (parameter, value), but removing the add_
prefix. We add all of them to a list and you will end up having the values list of attributes and a boolean that tell us if we want to add them to our query or not. [('fruits', True), ('vege', True)]
We iterate in values
list, and for every attribute that has True
we get the data from the class attribute using __getattribute__
method.
We will have a list of tuples of attributes, we just have to convert them to a list, in order to have all values that we want in a single list.
Now that we have the list of values, we just have to join
the list with ", " to comma space them.
And.. that's it..
Check the code below.
from dataclasses import dataclass
@dataclass
class Q:
fruits = ('taste', 'color', 'shine')
vege = ('is_green', 'color', 'juiceable')
meat = ('is_white', 'is_dark', 'is_red', 'meat_name')
carbs = ('is_refined', 'gi')
def get_fields(self, **kwargs):
values = [(key.replace('add_', ''), value) for key, value in kwargs.items()]
tuples_query = [self.__getattribute__(key) for key, value in values if value]
query = [field for single_tuple in tuples_query for field in single_tuple]
return ", ".join(query)
q = Q()
print(f"SELECT {q.get_fields(add_fruits=True, add_vege=True, add_meat=False)} from food_features")
This will output
SELECT taste, color, shine, is_green, color, juiceable from food_features