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