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