Search code examples
pythoninheritanceintrospection

Python Reference Subclass in a Static Method


This is going to be difficult to explain, but what I'm trying to do is create a Base object to base other objects on. The Base class handles shared tasks so that subclasses don't need to keep implementing them. However, I also need a static/class method which creates instances of the classes. So for example, this is my Base class:

class Base(object):
    def __init__(self, service, reference, vo=None):
        self.service = service
        self.reference = reference
        self.id = reference.getId()
        self.name = reference.getName()
        # do a database lookup here to get more information

    @staticmethod
    def get_objects(service, references, as_dict=False):
        """
        More efficient way to get multiple objects at once. Requires the service
        instance and a list or tuple of references.
        """
        vo_list = database.get_objects_from_references(references)
        items = list()
        for vo in vo_list:
            items.append(Base(service, vo.getRef(), vo))

        return items

The get_objects() method will take a list of ID numbers of entries stored in a database, then get all those objects and make objects out of them in one shot instead of hitting the database for each ID. The problem I'm having is that I have to use Base() in that method to instantiate the class. But this instantiates the Base class, not the subclass:

class Something(Base):
    def __init__(self, service, reference, vo=None):
        Base.__init__(self, service, reference, vo)
        do_extra_stuff()

My problem is I don't know if I do this:

Something.get_objects(service, references)

Will that just run Base's init() method, or will it run the subclass's init() method (and the do_extra_stuff() method)?


Solution

  • You want a class method instead, that will get the class object as its first parameter so that you can build an instance of that specific class:

    @classmethod
    def get_objects(cls, service, references, as_dict=False):
        """
        More efficient way to get multiple objects at once. Requires the service
        instance and a list or tuple of references.
        """
        vo_list = database.get_objects_from_references(references)
        items = list()
        for vo in vo_list:
            items.append(cls(service, vo.getRef(), vo))
    
        return items