Creating new instances of subclasses.
Terry Reedy
tjreedy at udel.edu
Wed Jan 7 13:11:09 EST 2009
J. Cliff Dyer 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')
>>>> f1.data
> 'abc'
>>>> f2.data
> 123
>>>> f3.data
> ['D','E','F']
>>>> type(f1)
> <class '__main__.StringField'>
>>>> type(f2)
> <class '__main__.StringField'>
>>>> type(f3)
> <class '__main__.ListField'>
>
> I've come up with a solution, but I suspect there's something cleaner
Make your master class _Field and make Field a factory function that
returns the proper subclass instance. The body of Field could be the
body of __new__ below. Then dump the __new__ methods.
tjr
I
> can do with the inheritance structure of __new__. I don't like
> explicitly leapfrogging over Field.__new__ to object.__new__.
>
> My attempt is below:
>
> def is_list(arg):
> if ',' in arg: return True
> else: return False
>
> def is_integer(arg):
> try: int(arg)
> except ValueError: return False
> else: return True
>
> class Field(object):
> def __new__(cls, a):
> if is_list(a):
> return ListField(a)
> elif is_integer(a):
> return IntegerField(a)
> else:
> return StringField(a)
>
> def __init__(self, input):
> super(Field, self).__init__(input)
> self.data = input
>
> class IntegerField(Field):
> def __new__(cls, a):
> return object.__new__(cls, a)
> def __init__(self, s):
> super(IntegerField, self).__init__(s)
> self.s = int(self.s)
>
> class ListField(Field):
> def __new__(cls, a):
> return object.__new__(cls, a)
> def __init__(self, s):
> super(ListField, self).__init__(s)
> self.s = s.split(',')
>
> class StringField(Field):
> def __new__(cls, a):
> return object.__new__(cls, a)
>
> Is there a cleaner way to do this? The main problem is that
> Field.__new__ gets in the way of properly constructing the subclasses
> once I've used it to select the proper subclass in the first place.
>
> Cheers,
> Cliff
>
More information about the Python-list
mailing list