0

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.

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?

4
  • 1
    You say you wish to call feed on the classes … these are modules … hence why it’s not there … Commented Aug 11, 2022 at 11:40
  • Okay and I get the class then instead of the module? Commented Aug 11, 2022 at 11:42
  • I think you are importing the 'Module' but not creating the objects. After module = __import__(name), add {obj = module.name} and then change module.feed() to obj.feed() Commented Aug 11, 2022 at 11:43
  • 1
    getattr(module, name)().feed() Commented Aug 11, 2022 at 11:43

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.