Creating new instances of subclasses.
J. Cliff Dyer
jcd at sdf.lonestar.org
Fri Jan 9 10:50:15 EST 2009
Thanks for the solutions everyone! I'm not sure which I'll end up
using, but I think I've got a better grasp of the problem now.
Cool stuff.
Cheers,
Cliff
On Thu, 2009-01-08 at 06:52 -0800, Paul McGuire wrote:
> On Jan 7, 12:00 pm, Paul McGuire <pt... at austin.rr.com> wrote:
> > On Jan 7, 10:38 am, "J. Cliff Dyer" <j... at unc.edu> wrote:
> >
> > > I want to be able to create an object of a certain subclass, depending
> > > on the argument given to the class constructor.
> >
> > > I have three fields, and one might need to be a StringField, one an
> > > IntegerField, and the last a ListField. But I'd like my class to
> > > delegate to the proper subclass automatically, so I can just do:
> >
> > > >>> f1 = Field('abc')
> > > >>> f2 = Field('123')
> > > >>> f3 = Field('D,E,F')
> >
> > O-O is not always the solution to every problem. Since inheritance is
> > getting in your way, try using a class-level factory method. Instead
> > of using the Field constructor, use a staticmethod of Field, something
> > like:
> >
> > @staticmethod
> > def make_Field(a)
> > if is_list(a):
> > return ListField(a)
> > elif is_integer(a):
> > return IntegerField(a)
> > else:
> > return StringField(a)
> >
> > and then get rid of all those __new__ methods, too.
> >
> > -- Paul
>
> After looking this over a bit more, I decided I didn't like make_Field
> having to know the criteria for creating the different subclasses, but
> wanted to put the smarts into the subclasses themselves. Here is an
> excerpt that shows this working:
>
> class Field(object):
> def __init__(self, input):
> super(Field, self).__init__(input)
> self.data = input
>
> @staticmethod
> def make_Field(a):
> subs = (ListField, IntegerField, StringField)
> ret = None
> for cls in subs:
> try:
> ret = cls(a)
> except TypeError:
> continue
> else:
> break
> return ret
>
> class IntegerField(Field):
> def __new__(cls, a):
> if not is_integer(a):
> raise TypeError()
> return Field.__new__(cls, a)
>
> ...
> ListField has a similar __new__ method, and StringField just creates
> the object, with no validation.
>
> make_Field still has to know what order to list the subclasses in
> (StringField is the most permissive, and so must come last in the list
> of subclasses), but the specific type tests are moved into the
> subclasses, which is a more appropriate place I think.
>
> -- Paul
> --
> http://mail.python.org/mailman/listinfo/python-list
>
More information about the Python-list
mailing list