Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Python dynamically import classes an call their functions

I have one Abstract Animal class.

from abc import ABC, abstractmethod


class Animal(ABC):  # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass

And three classes which Implements it

from Animal import Animal

class Lion(Animal):
   def feed(self):
        print("Feeding a lion with raw meat!")

from Animal import Animal

class Panda(Animal):
    def feed(self):
        print("Feeding a panda with some tasty bamboo!")
from Animal import Animal


class Snake(Animal):
    def feed(self):
        print("Feeding a snake with mice!")

Now I just want to import all classes, which are in the project folder and call the feed function of all classes, when there is a feed function.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

from glob import glob
import os

if __name__ == '__main__':
   for file in glob(os.path.join(os.path.dirname(os.path.abspath(__file__)), "*.py")):
       name = os.path.splitext(os.path.basename(file))[0]
       # add package prefix to name, if required
       module = __import__(name)
       try:
            module.feed()
       except Exception as e:
            print(e)

My Problem is now, that I get the errors:

module ‘Animal’ has no attribute ‘feed’

module ‘Lion’ has no attribute ‘feed’

module ‘main’ has no attribute ‘feed’

module ‘Panda’ has no attribute ‘feed’

module ‘Snake’ has no attribute ‘feed’

Can someone help me with this?

>Solution :

I take it your files are called Snake.py, Panda.py etc. If so then you are invoking feed() on the files not the classes. You need to get the modules (which you’ve done), then get the class and then call the method:

from glob import glob
import os

if __name__ == '__main__':
   for file in glob(os.path.join(os.path.dirname(os.path.abspath(__file__)), "*.py")):
       name = os.path.splitext(os.path.basename(file))[0]
       if name == "Animal" or name == "main":  # avoid main.py and Animal.py
           continue
       # add package prefix to name, if required
       module = __import__(name)
       try:
           # get the class
           cls = getattr(module, name)
           # instantiate the class and call the method
           cls().feed()
       except Exception as e:
            print(e)

Ive also included a safety check to exclude main.py and Animal.py

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading