Replacing methods without subclassing

Alex Martelli aleax at aleax.it
Mon Jan 27 02:03:02 EST 2003


xtian wrote:
> Aum <spam-me at no-thanks.com> wrote in message
   ...
>> def setevhandler(self, func):
>>         """
>>         Assigns a new event handler function to the class (or subclass)
>>         instance. This provides an alternative to subclassing.
>>         """
>>         cls = self.__class__
>>         if type(func) is not types.FunctionType:
>>                 raise MyNotFunctionError
>>         self.handleevent = new.instancemethod(func, self, cls)
> 
> That is simpler, but type-checking (the "if type(func)" line) is
> almost always a bad idea, preventing potentially useful polymorphism.

True!  However, in my opinion, in this case "the rot goes deeper"...


>  def setevhandler(self, func):
>          """
>          Assigns a new event handler function to the class (or
> subclass)
>          instance. This provides an alternative to subclassing.
>          """
>          cls = self.__class__
>          if not callable(func):
>                  raise CallableRequiredError
>          self.handleevent = new.instancemethod(func, self, cls)

This uses the same (generally inferior) coding pattern, known
as "look before you leap".  You check that func is callable,
then, if it is, call another function which ALSO (necessarily!)
checks the very same thing.  More often than not it's better
to rely on the checks that are ALREADY done, and which result
in exceptions being raised for inacceptable values.  This is
known as the "easier to get forgiveness than permission" coding
pattern.  You could code this functionality as:

def setevhandler(self, func):
    cls = self.__class__
    try: self.handleevent = new.instancemethod(func, self, cls)
    except TypeError: raise CallableRequiredError

Actually, I would normally not bother with the try/except and
raise here -- just propagate the TypeError upwards, it's simpler
and normally provides the functionality you need -- but I'm
leaving the code as is to show how easy it is to change the
exception if that is what you want.


Alex





More information about the Python-list mailing list