Calling superclass method with variable args?

Steve Johnson slj at pixar.com
Thu Jul 15 14:35:10 EDT 1999


Hi,

I'm a long-time C++ programmer, but I'm really new to Python, so please
forgive me if this is a dumb question with a simple or obvious answer.

A fundamental idea in OOP is the ability to have a subclass augment the
behavior of a superclass's method by redefine that method, and then
calling the superclass's version of the method before doing anything
else.  The key to this idea, and to polymorphism in general, is that the
two methods have the same argument signature so that the superclass's
method gets passed the same set of arguments from the caller whether the
subclass overrides the method or not.

If these methods have a static argument list, this is an easy thing to
do in Python. Here's an example:

class Task:
    def __init__(self,a,b,c):
        <whatever>

class Job(Task):
    def __init__(self,a,b,c):
        Task.__init__(self,a,b,c)
        <whatever>

aJob = Job(x,y,z);

But what if the method takes unnamed positional and keyword arguments.
Then, how do you pass these along to the superclass's version of the
method such that it gets the arguments in the same form that the
subclass's method did?  Here's the code in question:

class Task:
    def __init__(self,a,b,c,*moreargs,**morekeyargs):
        <whatever>

class Job(Task):
    def __init__(self,a,b,c, *moreargs, **morekeyargs):
        Task.__init__(self,a,b,c,?????)
        <whatever>

aJob = Job(x,y,z,m1,m2,m3,m4,m5);

My question really is...what do I replace the ????? (or that whole line)
with to get this fundamental OOP behavior?

This doesn't work:

        Task.__init__(self,a,b,c,moreargs,morekeyargs)

because now Task.__init__ will see exactly 5 arguments, instead of some
arbitrary number.  This almost works:

        apply(Task.__init__,(self,a,b,c) + moreargs)

but the extra keyword arguments don't get passed along. So, I took the
idea one step further and tried to introduce the keyword arguments back
into the parameter list that gets passed to apply:

def reconstruct(attribs):
    r = ()
    for key in attribs.keys():
        r = r + (key + "=" + attribs[key]",)
        print r
    return r

class Task:
    def __init__(self,a,b,c,*moreargs,**morekeyargs):
        <whatever>

class Job(Task):
    def __init__(self,a,b,c, *moreargs, **morekeyargs):
        apply(Task.__init__, (self,a,b,c) + moreargs +
reconstruct(morekeyargs))
        <whatever>

aJob = Job(x,y,z,m1,m2,m3,m4,m5);

but Task.__init__() doesn't recognize the keyword parameters as such,
instead it thinks they are string arguments of the form "foo=bar".

Can anyone tell me how to get the classic OOP behavior I'm looking for
here?

TIA,

Steve Johnson
Pixar Animation Studios






More information about the Python-list mailing list