Creating new instances of subclasses.

J. Cliff Dyer jcd at unc.edu
Wed Jan 7 11:38:29 EST 2009


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 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

-- 
Oook,
J. Cliff Dyer
Carolina Digital Library and Archives
UNC Chapel Hill




More information about the Python-list mailing list