Overriding methods on a per instance basis

Steve D'Aprano steve+python at pearwood.info
Sun May 14 12:01:47 EDT 2017


It is common to add an attribute to a class, then over-ride it in the
instance:


class Document:
    pagesize = "A4"

    def __init__(self, pagesize):
        self.pagesize = pagesize


A little-known fact, not appreciated by users of less powerful OOP
languages: Python supports per-instance customized methods too, since
methods are just attributes.


py> class Parrot:
...     name = "Polly"
...     def speak(self):
...         return "%s wants a cracker!" % self.name
...
py> petey = Parrot()
py> petey.speak()
'Polly wants a cracker!'


We can shadow petey's "speak" method with a callable:

py> petey.speak = lambda: "Who's a cheeky boy then!"
py> petey.speak()
"Who's a cheeky boy then!"


Notice that using a regular function means that we cannot access "self". But
all is not lost! We can do so by using a method object bound to the
instance:

py> from types import MethodType
py> petey.speak = MethodType(
...     lambda self: "%s is a cheeky boy!" % self.name, 
...     petey)
py> petey.speak()
'Polly is a cheeky boy!'




This can be considered a form of the Strategy design pattern. From
Wikipedia:

    ... the strategy pattern (also known as the policy pattern) 
    is a behavioural software design pattern that enables an 
    algorithm's behavior to be selected at runtime. The strategy 
    pattern:

    - defines a family of algorithms,
    - encapsulates each algorithm, and
    - makes the algorithms interchangeable within that family.

https://en.wikipedia.org/wiki/Strategy_pattern

the major difference being is that in the Strategy pattern there is not
necessarily a default implementation provided by the class:

class Dog:
    pass

rover = Dog()
butch = Dog()
laddie = Dog()

rover.do_trick = fetch_stick
butch.do_trick = play_dead
laddie.do_trick = solve_world_hunger




-- 
Steve
Emoji: a small, fuzzy, indistinct picture used to replace a clear and
perfectly comprehensible word.




More information about the Python-list mailing list