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
--
http://mail.python.org/mailman/listinfo/python-list