1

I have a database class that stores the objects in database.py:

class Database(dict):
    def get_objects_by_object_type(self, object_type):
        # get a list of objects based on object type


db = Database()

and then I have these two classes in models.py:

class IdentifiableObject(object):
    def __init__(self, object_id):
        self.object_id = object_id
        self.object_type = self.__class__.__name__.lower()

    @classmethod
    def get_object_type(cls):
        return f"{cls.__name__.lower()}"


class Ingredient(IdentifiableObject):
    def __init__(self, object_id, unsuitable_diets=[]):
        super(Ingredient, self).__init__(object_id=object_id)
        self.unsuitable_diets = unsuitable_diets

How can I get objects by type: for example, if I pass an object of type ingredient it should get all ingredients and return it.

# Ingredient.get_object_type() is equal to 'ingredient'


ingredients = db.get_objects_by_object_type(object_type=Ingredient.get_object_type())
Mahdi Jafari
  • 347
  • 6
  • 22
  • `type(o)` will give you the type of the object (o) - is that what you are asking? – Matt Clarke Sep 28 '22 at 05:37
  • Thanks @MattClarke for your comment. I want to get all objects with the type of `ingredient`. I am not sure what to pass inside `type` as the parameter. – Mahdi Jafari Sep 28 '22 at 05:43
  • One comment: don't use mutable value as default argument value. `unsuitable_diets=[]` can lead to lots of tricky issues. – hide1nbush Sep 28 '22 at 05:53

2 Answers2

1

This is one way to identify objects by type:

class MyClass:
    pass

some_objects = [5, "string", MyClass()]

for o in some_objects:
    if type(o) == MyClass:
        print("Found item of MyClass")
Matt Clarke
  • 757
  • 4
  • 15
1

I assume this snippet will work for you. Leave comments if I misunderstand your question.

class IdentifiableObject(object):
    def __init__(self, object_id):
        self.object_id = object_id
        self.object_type = self.__class__.__name__.lower()

    @classmethod
    def get_object_type(cls):
        return f"{cls.__name__.lower()}"


class Ingredient(IdentifiableObject):
    def __init__(self, object_id, unsuitable_diets):  # don't use mutable value as default argument value.
        super(Ingredient, self).__init__(object_id=object_id)
        if unsuitable_diets is None:
            unsuitable_diets = []
        self.unsuitable_diets = unsuitable_diets


class Database(dict):
    def get_objects_by_object_type(self, object_type):
        return [values for values in self.values() if values.get_object_type() == object_type]


if __name__ == '__main__':
    db = Database({
        "1": IdentifiableObject(1),
        "2": Ingredient(2),
        "3": Ingredient(3),
    })
    ingredients = db.get_objects_by_object_type(Ingredient.get_object_type())
    identifiable_objects = db.get_objects_by_object_type(IdentifiableObject.get_object_type())
    print(ingredients)
    print(identifiable_objects)

Outputs:

[<__main__.Ingredient object at 0x10a933880>, <__main__.Ingredient object at 0x10a933820>]
[<__main__.IdentifiableObject object at 0x10a9338e0>]
hide1nbush
  • 759
  • 2
  • 14
  • Thank you so much @hide1nbush. It works now. I didn't get what `self.values` is? Could you please tell me about it? – Mahdi Jafari Sep 28 '22 at 06:10
  • 1
    of course. @MahdiJafari since your `Database` is inherited from `dict`, you can call `self.values()` to get a view object that displays a list of all the values in the `db` object. Similar functions include `items()`, returns a view object that displays a tuple of all the k, v pairs, `keys()`, returns a view object that displays a list of all the keys. Note that `a view object that displays a list of ...` is different from `a list`. You may need to cast it: `list(self.values())`. See this thread for more info: https://stackoverflow.com/questions/16228248/how-can-i-get-list-of-values-from-dict – hide1nbush Sep 28 '22 at 06:17