Inheritance and forward references (prototypes)

Rhodri James rhodri at wildebst.demon.co.uk
Sun Jun 21 01:18:31 CEST 2009


On Sat, 20 Jun 2009 21:26:56 +0100, Lorenzo Di Gregorio  
<lorenzo.digregorio at gmail.com> wrote:

> Thank you for your help: I'm working on a rather large source, but I
> think I have isolated the problem now.
> This listing generates an error:
>
> -----------------------------------------------
> class BaseA(object):
>     def __init__(self):
>         return
>
> class DebugA(BaseA):
>     def __init__(self):
>         return
>
> class B(object):
>     def __init__(self,test=A()):
>         self.obj = A()
>         return
>
> if __name__ == "__main__":
> #    class A(BaseA): # Uncomment this for using BaseA objects
> #        pass
>      class A(DebugA): # Uncomment this for using DebugA objects
>          pass
> -----------------------------------------------
>
> The error happens because Python apparently evaluates the named
> arguments before running the script.
> I think I have read something about this some (long) time ago but I
> can't find it anymore.

I could have sworn this was in the FAQ, but apparently not.  You're
right, Python evaluates the default arguments when it executes the
`def` instruction.  (Yes, `def` is an executable instruction.  It's
got to create the function/method object after all!)

The usual fix is not to make the default an instance of A (which
will have all sorts of other side effects as well, since the same
instance of A will be shared by all the Bs that don't supply a
`test` parameter), but to use `None` as a marker.

class B(object):
     def __init__(self, test=None):
         if test is None:
             test = A()
         self.obj = A()

and so on.
-- 
Rhodri James *-* Wildebeest Herder to the Masses



More information about the Python-list mailing list