On Wed, 2003-05-28 at 18:13, Stacy Roberts Ladnier wrote:
Why not create a single product that can instantiate itself (or subobjects) more than one way?
The product I am creating is more like an application.
Excellent.
It has container objects at the top,
Cool.
and several subfolders
OK.
that contain hundreds of objects
Yeah.
that make up a 'record'.
Hundreds of objects == one "record"? Hmmm...
I guess you can say I have tons of data models to go in this application.
That's not typically a hallmark of good design or an easily-supported system, but I'm not the one with the requirements in front of me.
My whole problem is trying to get things to instantiate more than one way.
Ah... well, in that case I have a couple cool tricks to share.
Once a user has created a record of type #1, he must have the ability to go back and add an extension of type A.
So... this is a "record" in the same sense as above where a record is defined by hundreds of ZMI objects? Does the "extension" consist of an additional object added through the ZMI? Or do you just want your type #1 object to have a new interface?
I can't force the user to create a record of tye #1 with the type A extension up front.
Why not? Anything a user can do, Zope can do for them.
If only it were that easy, I wouldn't be having such a pain.
Often when things are difficult in Zope (and open source in general), it is because one is unaware that someone else already solved the problem. Leaving that aside, there's a couple different ways you could attack the problem of returning different types of instances If you want the decision made at instantiation time, you can do that in your constructor method: -------- manage_addMyThing(self, id, REQUEST=None): if some_test: self._setObject(id, Class1(id)) else: self._setObject(id, Class2(id)) class Class1: def __init__(self, id): self.id = id meta_type = 'MyThing' class Class2: def __init__(self, id): self.id = id meta_type = 'MyThing' -------- You'll want to ensure that both classes either have the same interface (recommended) or at least have an intelligent way of failing when a given interface isn't found. Having them both inherit from a base class is an approach well worth considering. If you want to be able to change classes on the fly, that's a bit trickier, but not by much. ------ class One: def __init__(self, name): self.name = name def whoami(self): return self.name class Two: def __init__(self, name): self.name = name def whoami(self): return "I am %s, a class Two object." % self.name def SwitchClass(object, target_class): if target_class == 'One': new_obj = One(object.name) if target_class == 'Two': new_obj = Two(object.name) new_obj.__dict__ = object.__dict__ return new_obj ------- If you entered these classes into an interactive prompt, you can then see how easily you can change back and forth:
a = One('my thing') a.foo = 'this is the foo attribute' a.whoami() 'my thing' a = SwitchClass(a, 'Two') a.whoami() 'I am my thing, a class Two object.' a.foo 'this is the foo attribute'
The execution in a Python product may be a bit more sophisticated, but the general idea is the same. Python makes it pretty easy to change stuff on the fly and makes it easy to use objects polymorphically so that what type your object is often doesn't matter very much. Hope that helps and if you want to hash out some possible alternatives to your data model, let us know. Dylan