overriding methods - two questions

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Fri Nov 16 17:03:26 EST 2007


On Fri, 16 Nov 2007 18:28:59 +0100, Bruno Desthuilliers wrote:

>> Question 1:
>> 
>> Given that the user of the API can choose to override foo() or not, how
>> can I control the signature that they use?
> 
> While technically possible (using inspect.getargspec), trying to make
> your code idiot-proof is a lost fight and a pure waste of time.


Worse: it's actually counter-productive!

The whole idea of being able to subclass a class means that the user 
should be able to override foo() *including* the signature. Why do you 
want to stop them? It's their subclass, not yours. You don't know what 
arguments it needs.

Let me give a practical example: in mathematics there is a construct 
known as a continued fraction. What it is isn't especially important, if 
you're curious you can google for it. If you were defining a class for 
continued fractions, you might do this:

class ContinuedFraction(object):
    def __init__(self, list_of_numerators, list_of_denominators):
        pass
    # lots of other methods

cf = ContinuedFraction([3, 7, 2, 8, 9, 5], [2, 3, 1, 5, 3, 7])

If I wanted to subclass your ContinuedFraction class to provide regular 
continued fractions, I could do this:

class RegularCF(ContinuedFraction):
    def __init__(self, *denominators):
        numerators = [1]*len(denominators)
        super(RegularCF, self).__init__(numerators, denominators)
    # all other methods are inherited from super-class without change

cf = RegularCF(4, 9, 1, 2, 6, 3)


But if you did what you're proposing to do, I couldn't do that. I'd need 
to do something silly like this:

class RegularCF(ContinuedFraction):
    def __init__(self, list_of_numerators, list_of_denominators):
        numerators = [1]*len(list_of_denominators)
        super(RegularCF, self).__init__(numerators, list_of_denominators)

cf = RegularCF(None, [4, 9, 1, 2, 6, 3])


just so that the signatures matched. What a waste of time. 

And worse, what if my subclass needed *more* arguments than your 
signature provided? The hoops I would have to jump through would not only 
be flaming, they'd be spinning and flying through the air, with rotating 
knives and trip-wires.



-- 
Steven



More information about the Python-list mailing list