Invoking a subclass's method on its superclass's instance

Jeremy Hylton jeremy at beopen.com
Mon Sep 25 15:07:40 EDT 2000


Rick Lee <rwklee at home.com> writes:

> I like to be able to invoke a subclass's method on an instance of its
> superclass, also this method makes changes to the instance's data.
> 

This is a strange request.  If the method is defined in a subclass,
presumably it depends on state or behavior that is also defined in
that subclass.  What if the instance you are trying to invoke the
method on doesn't have the same state/behavior?

If you are designing the class hierarchy, wouldn't it be easier to
organize the classes so that the method is defined in the superclass,
possibly with hooks for overriding or specialization in the subclass.

Perhaps you could explain what you are trying to accomplish in a bit
more detail and you could get better advice.  The feature's you are
proposing to use are useful for introspection, but I would be wary of
any package that uses them for its normal operation.

> So far, I found these two methods that seem to work:
> 
> Method 1, changing superclass instance's __class__ to subclass:
> 
> >>> x = superclass()
> >>> x.__class__ = subclass
> >>> x.method()  # this executes method defined in subclass
> 

This method changes the class of x into subclass.  This is a dangerous
feature, but can be useful for mode-switching operations.

> Method 2, creating a subclass instance, and change its __dict__ to
> reference superclass instance's:
> 
> >>> x = superclass()
> >>> y = subclass ()
> >>> y.__dict__ = x.__dict__
> >>> y.method () # since y.__dict__ refers to x's data, x's data gets
> changed by method
> 
> Are these two methods totally equivalent?  Are there any gotcha's?  Is
> there a more elegant way?

This causes x and y to share the same dictionary.  I guess this works
but it is fairly obscure and fragile.

> Note, the following did not work, resulting with the TypeError below:
> 
> >>> x = superclass()
> >>> subclass.method (x)
> 
> TypeError: unbound method must be called with class instance 1st
> argument
> 
> (The error message is somewhat misleading.)
>

Yes, a little misleading.  It is complaining because x is not an
instance of subclass.  A more verbose error message might have made it
clearer, but I'm not sure: "unbound method must be called with
instance of class defining method (or its superclass) as first
argument."

-- Jeremy Hylton <http://www.python.org/~jeremy/>



More information about the Python-list mailing list