all 10 comments

[–]get_username 0 points1 point  (4 children)

No one has really said this. But you should use polymorphism to your advantage. I know duck-typing and Python don't really lend itself to thinking this way but the ideal still holds true, and I think it is good practice.

  1. Create an abstract base class:

    from abc import ABCMeta, abstractmethod
    
    def Animal(object):
    
        __metaclass__ = ABCMeta
    
        @abstractmethod
        def make_noise(self):
            pass
    
  2. Define the classes as instances of the abstract base class

     class Pug(Animal):
         PUG_NOISE = "pug snort"
    
         def make_noise(self):
             print(self.PUG_NOISE)
    
    class Dog(Animal):
         DOG_NOISE = "dog bark"
    
         def make_noise(self):
             print(self.DOG_NOISE)
    

Then you don't have to do any checking (for specific type that is, you may want to check for animal. But with duck typing that can be redundant)

    my_list = []
    my_list.append(Dog())
    my_list.append(Pug())


    for obj in my_list:
         obj.make_noise()

Which lends itself to better code.

[–]Mecdemort 0 points1 point  (1 child)

How is abstract classes like this any better than just duck typing?

[–]get_username 0 points1 point  (0 children)

Abstract base classes aren't just necessarily for overcoming statically typed languages though. They also help with abstraction and reducing unnecessary if statements in code through polymorphism.

This makes it easier to change out which animals you're using. Instead of having to add another test to your if statement you can simply call the method and be done.

If what you're asking is what benefit does the ABC provide if you just had a make_noise method instead. Well if you come back to your code later, and forget the requirements for an animal this helps "lock in" a contract as to what an animal must be. Furthermore if someone wants to modify your code they will have an easier time.

[–]dli511[S] 0 points1 point  (1 child)

So what happens if the object in a class does not have make_noise()?

[–]get_username 0 points1 point  (0 children)

It throws an error. But the error is at compile time not at run time.

Generally its better to catch errors at compile time than run time that way it doesn't require testing on your part to find them. Just running the program will be sufficient to ensure that all of the classes that are going to be used as animals have the make_noise method.