Rafe wrote: > On Nov 21, 1:39 am, Steve Holden <[EMAIL PROTECTED]> wrote: >> Rafe wrote: >>> Hi, >>> I am in a situation where I feel I am being forced to abandon a clean >>> module structure in favor of a large single module. If anyone can save >>> my sanity here I would be forever grateful. >>> My problem is that classes in several modules share a common base >>> class which needs to implement a factory method to return instances of >>> these same classes. >>> An example to help illustrate what I mean: >>> Lets say I have the following modules with the listed classes: >>> - baselib.py with BaseClass >>> - types.py with TypeA, ... >>> - special.py with SpecialTypeA, ... >>> Which would be used a bit like this: >>>>>> type_a = any_type_instance.get_type("TypeA") >>>>>> special_type = type_a.get_type("SpecialTypeA") >>> Again, I can get around this by dumping everything in to one module, >>> but it muddies the organization of the package a bit. This seems like >>> a problem that would come up a lot. Are there any design paradigms I >>> can apply here? >> Well a simple way to do this is to observe that even when a base class's >> method is inherited by an instance of a subclass, when the method is >> called the type of "self" is the subclass. And you can call the >> subclass's type to create an instance. Perhaps the following code would >> make it more obvious: >> >> $ cat baseclass.py >> class Base(object): >> def factory(self, arg): >> return type(self)(arg) >> >> [EMAIL PROTECTED] /c/Users/sholden/Projects/Python >> $ cat subclass.py >> from baseclass import Base >> >> class sub(Base): >> def __init__(self, arg): >> print "Creating a sub with arg", arg >> >> s = sub("Manual") >> >> thing = s.factory("Auto") >> print type(thing) >> >> [EMAIL PROTECTED] /c/Users/sholden/Projects/Python >> $ python subclass.py >> Creating a sub with arg Manual >> Creating a sub with arg Auto >> <class '__main__.sub'> >> >> Hope this helps. >> >> regards >> Steve >> -- >> Steve Holden +1 571 484 6266 +1 800 494 3119 >> Holden Web LLC http://www.holdenweb.com/ > > Hi Steve, > > Correct me if I have this wrong, but the problem with your solution is > that it only creates a new instance of the same class, type(self), > while I need to return any number of different possibilities. > In that case you need to pass the type of the new instance you require as an argument to the factory method, I guess, or something similar. My example has each subclass returning instances of the subclass that was used to call the factory method, yes.
If A instances need to be able to get B instances and B instances need to be able to create B instances then you do indeed have a tricky problem when it comes to separating your classes into different modules,. But it's not insoluble! > I thought about getting the module from self... >>>> class base(object): >>>> def factory(self, type): >>>> module = sys.modules[self.__class__.__module__] >>>> return getattr(module, type) > > ...but my baseclass is used from several modules so this would be > inaccurate for me (the factory method only uses my 'types' module, so > a hard import works) > I am not sure yet if I understand the requirement properly. It seems from the above code that you always want to create instances of a named type defined in the same module as the subclass? > I'm still wondering what Arnaud meant by "make types register > themselves with the factory function" > You would have to ask him, but I suspect he means having each subtype call a method of the base type to add itself to some dictionary so you can call the factory method with a key that will tell it which subtype to produce. This is a fairly sensible way to separate definitions form references. regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/ -- http://mail.python.org/mailman/listinfo/python-list