""" barnyard.py An example illustrating python objects including the concepts of * class variables Animal.population, one for whole class * instance variables self.name, self.sound for each animal * "special" __str__ method str() output ; how the class prints * class inheritance "isa" relationship : "A Dog is a Animal." * a container class a class with instances of another within tests ----- >>> spot = Dog(name='Spot') >>> spot.speak() "A dog named 'Spot' says woof." >>> print(spot) Dog(name='Spot') >>> Cat().speak() 'A cat says meow.' $ python --version python 3.5.2 running it ---------- $ python barnyard.py The barnyard has 5 animals : A dog says woof. A cat says meow. A dog says woof. A dog says woof. A cat named 'Mr. Mistoffelees' says meow. Jim Mahoney | cs.marlboro.college | Oct 2018 | MIT License """ class Animal: """ The parent class for any sort of animal. """ # population is class variable - its full name is Animal.population. # Note that there is only one of these for the whole class, # not one per animal as is the case with instance variables. population = 0 def __init__(self, name=''): self.name = name Animal.population += 1 self.initialize() def initialize(self): """ Change this method for each particular animal ! """ self.sound = '?' def __str__(self): """ Return the string representation of this animal. """ if self.name: naming = "name='{}'".format(self.name) else: naming = '' return '{}({})'.format(self.__class__.__name__, naming) def speak(self): """ Return a string describing what this animal says. """ if self.name: named = "named '{}' ".format(self.name) else: named = '' return 'A {} {}says {}.'.format(self.__class__.__name__.lower(), named, self.sound) class Dog(Animal): """ A dog says woof. """ def initialize(self): self.sound = 'woof' class Cat(Animal): """ A cat says meow. """ def initialize(self): self.sound = 'meow' class Zoo: """ A bunch of animals that can each speak in turn. """ def __init__(self): Animal.population = 0 # The doc tests add extra animals ... self.animals = [] def add(self, animal): self.animals.append(animal) def print_chorus(self): """ Let the animals speak ... """ for animal in self.animals: print(animal.speak()) def main(): barnyard = Zoo() for creature in (Dog, Cat, Dog, Dog): # creature is a class ... barnyard.add( creature() ) # ... so this creates one! barnyard.add( Cat(name='Mr. Mistoffelees') ) # And one more, with a name. print('The barnyard has {} animals :'.format(Animal.population)) barnyard.print_chorus() if __name__ == '__main__': import doctest doctest.testmod() main()