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

Steve Holden sholden at holdenweb.com
Tue Sep 26 18:25:10 EDT 2000


Rick:

This is a fairly complex requirement, which I suspect you've abbreviated
somewhat to help us retain our sanity.  Therefore, I may be completely off
beam...

Rick Lee wrote:
> 
> I am trying to implement a simulator, ie. a simulated entity.  The model of the
> entity being simulated maps very well to a class structure, with approx. 10-20
> classes, each with approx. 10 methods.  The simulated entity will be used to
> test a product under development, ie., as far as the product under development
> is concerned, it can't tell the difference between the simulated entity and the
> real entity through the defined interface.  In order to test this product under
> development well, I would like to introduce unexpected behaviour and behaviour
> variants into the simulated entity, and see whether the product under test
> would react gracefully or properly.
> 
Had you though of using attributes, and setting them to unbound methods
or plain functions as appropriate?  The real methods could then just call
the attributes.

> Here are the major characteristics of this test system, germane to this
> discussion:
> 
> - When the test system is running, I like to be able to select a particular
> behaviour variant for a particular class instance, in order to perform a
> particular test.

I.e. you would change the appropriate attribute of that instance to the
function exhibiting the correct "pathological" behavior.

> - To allow for flexibility for complexity, I would like to be able to select a
> set of particular behaviour variants, each for a particular class instance,
> during each test.  To allow for this, I would restrict a behaviour variant as
> one that involves only one class method.

So you want to repeat a sequence of tests with a particular method iteratinf
over a defined set of functions?

> - In one test session, there will be many tests performed one after another.
> If things go well, I don't want to have to restart the test system between
> tests.

Perhaps you could define a method to put objects back into a "non-pathological"
state between tests (unless you want the to retain their current pathologies).

> - There will be literally hundreds of behaviour variants for each method of
> each class.

Sounds ugly.  I take it complete test coverage isn't a goal ...

> - They must reside in different modules, because they will be written and used
> by different testers; these testers will actually be users of this simulator,
> (and beginner Python coders).

So you want external code to access the guts of objects whose class is
defined in another module?  Python at least allows you to do this, and
of course there's nothing wrong with subclassing classes defined in
modules.

> - This gives rise to the concept of a reference behaviour: it is the default
> behaviour for each class method.  After each test, the system is quickly reset
> to its reference (default) behaviour set with all the class instances remain
> intact, and then another subset of behaviour variants is chosen for the next
> test.

So you *do* need a "restore" method.  Or possibly a "restore" method for
each method?

> - Quite often a behaviour variant is an extension to the reference behaviour;
> so I want to make this easy to do.

One solution might use lists of functions to represent the set of
mathods you want to concatenate, and then

	for f in functionlist:
		apply(f, args)

for example?  That way you can "add extra behavior" by appending another
function to the list.

> - I must be able to introduce a new behaviour variant(s) while the test system
> is running.

Well, this argues for attributes, I suspect.  You really don't want to go
changing instance methods willy nilly.

> - I must be able to save the simulated entity's state to a file; and reuse it
> to restart the test system some time later.  The state space is pretty complex;
> but it maps well to a class structure.
> 
As long as you don't revise class definitions too radically between runs you
should be able to pickle your state and restire it later.

> I thought a natural and elegant solution is to implement only the default
> behaviour in the reference model of class methods, and then implement each
> behaviour variant as a method of a subclass with the same method name as its
> superclass's.

This does indeed seem natural.  That's precisely what object-oriented
programming is intended to facilitate.  Is the problem that you want your
subclass instances to revert back to being superclass instances?  In that
case, perhaps your __init__ method should check for a subclass instance
and copy state from the subclass instance.  That way, you could morph your
pathological variants back to the superclass as required.

>		  As the test system starts, only the reference model starts up
> (in some test scenarios that is all that is needed.)  To begin a test, the
> tester will introduce his behaviour variants, and tell the test system to
> switch to them for a selected set of instances.  After the test, he tells the
> system to switch back to the reference behaviour; and then repeat for a
> different test.
> 
If you only want to set the subclass' methods to those of a superclass to
make your "pathological variants" revert back to standard behaviour, would
it not be better to simply re-create standard objects, copying whatever
state you needed to retain?

> Dave Brueck wrote:
> 
> > What exactly is the higher-level problem you are trying to solve?
> >
[ ... ]

It's almost as though the whole problem sapce representation should become
one huge data structure, which you use to drive your simulation.

Hope this helps.  If not, feel free to ignore it.

regards
 Steve
-- 
Helping people meet their information needs with training and technology.
703 967 0887      sholden at bellatlantic.net      http://www.holdenweb.com/





More information about the Python-list mailing list