#!/usr/bin/env python

import types

def method_property(name):
    def getter(self):
        return getattr(self, name)
    def setter(self, value):
        setattr(self, name, types.MethodType(value, self))
    return getter, setter

class Duck(object):
    def __init__(self, fly, quack):
        self.fly = fly
        self.quack = quack

    quack = property(*method_property("_quack"))
    fly = property(*method_property("_fly"))

    def swim(self):
        print "All ducks float, even decoys!"

class MallardDuck(Duck):
    def __init__(self):
        Duck.__init__(self, fly, quack)
        print "I'm a real Mallard Duck"

class ModelDuck(Duck):
    def __init__(self):
        Duck.__init__(self, fly_no_way, squeak_quack)
        print "I'm a Model Duck"

class DecoyDuck(Duck):
    def __init__(self):
        Duck.__init__(self, fly_no_way, mute_quack)
        print "I'm a Decoy Duck"

def fly(self):
    print "I'm flying!!"

def fly_no_way(self):
    print "I can't fly"

def fly_rocket_powered(self):
    print "I'm flying with a rocket!"

def quack(self):
    print "Quack"

def mute_quack(self):
    print "<< Silence >>"

def squeak_quack(self):
    print "Squeak"

if __name__ == "__main__":

    print '#'*80
    print "Mallard Duck"
    print '#'*80
    mallard = MallardDuck()
    mallard.quack()
    mallard.fly()

    print '#'*80
    print "Model Duck"
    print '#'*80
    model = ModelDuck()
    model.fly()
    model.fly = fly_rocket_powered
    model.fly()

    print '#'*80
    print "Decoy Duck"
    print '#'*80
    decoy = DecoyDuck()
    decoy.fly()
    decoy.quack()