Class hierarchy problem

Steven D'Aprano steve at pearwood.info
Tue Aug 6 05:36:20 EDT 2013


On Tue, 06 Aug 2013 11:10:17 +0200, BrJohan wrote:

> I'm in need of help to solve this Python (ver. 3.3) problem:
> 
> I have a hierarchy of classes (SubA, SubAB, SubB, ..., SubBCA,
> SubC,...), each of which is inheriting from a chain of superclasses with
> a common baseclass(Sup) on top. (So far, no problem)


Well, I don't know about that, a deep and complex chain of super- and sub-
classes already sounds like a problem. But putting that aside...


> Now, I want to create instances of the correct subclasstype as decided
> by the common baseclass, like this:
> 	
> i = Sup(args_allowing_the_baseclass_to_deduce_correct_subclass)

Inheritance doesn't, or at least shouldn't, work like that. The 
superclasses shouldn't be expected to know about their subclasses. 
Knowledge goes the other way: each class knows its parents, and so 
recursively can go all the way to the common base class.


> where i can be of any class except Sup itself (as decided by Sup)
> 
> Now, the problem:
> 
> How to design the __new__() and __init__() methods for the various
> classes in order to achieve what I want?

You don't :-)

Instead, have a factory function:

def sup(args):
    if args:
        return Sup(...)
    elif condition():
        return SupA(...)
    elif condition2() or condition3():
        return SupB(...)
    ...


sort of thing.


Another possibility would be to start with the child class, and give it 
the ability to return an instance of itself, or its direct parent. 
Completely untested:


class SupABC(SupABB):
    def __new__(cls, args):
        if condition():
            # Return an instance of myself.
            ...
         else:
            # Let my parent (maybe) return an instance.
            return SupABB(args)


Either way, the design risks becoming a horrible mess, but you might be 
able to use it. Good luck!


-- 
Steven



More information about the Python-list mailing list