0

I want to be able to instance an object and interact with it without knowing what the specific type of that object will be at the onset. Basically, I want to have the object take on the properties specified say in a config file, but then interact with it using a uniform handle.

I'm trying to decide whether I need to use Python inheritance or nested/inner classes for the following example.

For example, I would like to do the following

config.animal_type = 'Squirrel'
a = Animal()
a.walk()
I'm walking on 4 legs!

config.animal_type = 'Monkey'
b = Animal()
b.walk()
I'm walking on 2 legs!

The class structure would look similar to what I have below, but I would use the config.animal_type variable to decide what kind of type a & b would be.

class Animal:
    def __init__(self)
        ...
    def walk(self)
        ...
    def eat(self)
        ...

class Squirrel(Animal):
    def walk(self):
        self.walk_on_4_legs()
        super().walk()

    def walk_on_4_legs(self):
        print("I'm walking on 4 legs!")


class Monkey(Animal):
    def walk(self):
        self.walk_on_2_legs()
        super(Monkey, self).walk()

    def walk_on_2_legs(self):
        print("I'm walking on 2 legs!")

Alternatively, I've also been investigating using nested/inner classes, where I would only define Squirrel and Monkey classes inside the Animal class, and then declare the object only based on the config variable. The only thing is I've read that nested/inner classes aren't advisable as a best practice.

I would appreciate clarification as to the best method to implement this functionality.

Azmat
  • 97
  • 1
  • 11
  • Inheritance, definitely. How you use the value of `config.animal_type` to select which class to instantiate is another question. – chepner Jan 02 '20 at 20:23
  • I'm not sure how a nested/inner class would even be a solution, inheritance seems suitable here. Although maybe not strictly necessary due to Python's duck typing. You probably want a factory which you pass your config to which will choose the type, because using `a = Animal()` will always give you an `Animal`, not a `Monkey`, unless you do some serious shenanigans. So, `a = factory(config)` would return an object of the type specified by your config. – juanpa.arrivillaga Jan 02 '20 at 20:47
  • I agree the inheritance would be the best solution. You can use a factory function or method to instanciate the proper derived subclass. See my answer to [Improper use of __new__ to generate classes?](https://stackoverflow.com/questions/28035685/improper-use-of-new-to-generate-classes) for an example of a very flexible way doing it via the class' `__new__()` method. – martineau Jan 02 '20 at 21:30

0 Answers0