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...@austin.rr.com> wrote: > > On Jan 7, 10:38 am, "J. Cliff Dyer" <j...@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 > -- http://mail.python.org/mailman/listinfo/python-list