[Tutor] Handling function parameters of mixed object and basic types
alan.gauld at freenet.co.uk
Mon Sep 4 12:40:20 CEST 2006
> I've taken over someone else's code (yes, honestly!) that has a
> complex class hierarchy on top of the main procedural code. This
> is unfortunate because it means that isinstance() is everywhere.
It shouldn't do. Multiple uses of isinstance is usually a sign
of bad OO design, regardlerss of whether procedurak code is
involved or not.
As you go on to prove... :-)
> def newOutput(x):
> if x is None:
> except AttributeError:
> if isinstance(x, int):
> elif isinstance(x, float):
> elif isinstance(x, str):
> However, when I verified this example using timeit, the results were
> completely unexpected. The time to resolve the objects remains the
> same, but for the built-in types raising and catching the exception
> means that resolution of built-in types takes 3 or 4 times longer.
Yes, thats because whehn you call x.output when the method doesn't
exist Python has to navigate the entire class heirarchy looking for
missing method before it can return the exception.
The solution is to extend the logic you used for N0one - ie put all
non object cases first, then, only if it is an object, use isinstance.
That should keep the speed up for the primitive types but keep the
clean design for the OOP stuff. If you don't like that layout then
you could do an isinstance call on a common superclass before
invoking the method.
> The improved robustness of the code for objects is obviously good,
> but not at the expense of killing performance for the built-in
> Have I made a basic boo-boo in my test code? Is there a better way
> of speeding up the original function? I don't really want to spend
> hours (days?) implementing this in the real code if I'm barking up
> the wrong tree.
Personally I'd just keep all the exception types together at the top.
More information about the Tutor