Creating new instances of subclasses.

Paul McGuire ptmcg at austin.rr.com
Thu Jan 8 09:52:15 EST 2009


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



More information about the Python-list mailing list