T
telesphore4
Is there a better way to make the subclassing of built-in types stick?
The goal is to have the the fields of a class behave like strings with
extra methods attached. That is, I want the fact that the fields are
not strings to be invisible to the client programmers. But I always
want the extras to be there for the clients too.
What I'm doing is subclassing str. Of course, whenever you then set
mystr = 'a string' you loose the extra goodies that I have attached in
the subclass. So, to get around this I set up __get__ers and __set__ers
for the fields.
The question is there a more succinct way to have the extended string
behavior stick than using descriptors?
Just to make things concrete here's some abbreviated sample code:
class Person(Table.Table):
def __init__(self, tcs, gender=None, first=None, last=None,
status=None):
self.gender = gender
self.first = first
self.last = last
self.status = status
# Using mix-ins to get the desired behavior
class Gender(Field.InitAlways, Field.SqlVarchar):
table = ('F', 'M')
fillNext = -1
@classmethod
def fill(cls, rec):
cls.fillNext += 1
return cls.table[cls.fillNext % 2]
#classes First, Last, & Status are analogous but more complicated
# The descriptors are set up at the bottom of the module like so:
Person.first = Field.Descriptor(First)
Person.gender = Field.Descriptor(Gender)
Person.status = Field.Descriptor(Status)
# Moving along to other stripped supporting code
class Descriptor(object):
def __init__(self, cls, name=None):
self.cls = cls
if name == None:
self.name = cls.__name__.lower()
else:
self.name = name.lower()
def __set__(self, inst, value):
if inst.__dict__.has_key(self.name):
inst.__dict__[self.name] = self.cls(inst, value, True)
else:
inst.__dict__[self.name] = self.cls(inst, value, False)
class InitAlways(str):
def __new__(cls, rec, value, reset):
if reset:
return str.__new__(cls, value)
if value == Empty:
return str.__new__(cls, '')
if value == Fill or value == None: #if value in (None, Fill,
''):
return str.__new__(cls, cls.fill(rec) or '')
return str.__new__(cls, value or '')
The goal is to have the the fields of a class behave like strings with
extra methods attached. That is, I want the fact that the fields are
not strings to be invisible to the client programmers. But I always
want the extras to be there for the clients too.
What I'm doing is subclassing str. Of course, whenever you then set
mystr = 'a string' you loose the extra goodies that I have attached in
the subclass. So, to get around this I set up __get__ers and __set__ers
for the fields.
The question is there a more succinct way to have the extended string
behavior stick than using descriptors?
Just to make things concrete here's some abbreviated sample code:
class Person(Table.Table):
def __init__(self, tcs, gender=None, first=None, last=None,
status=None):
self.gender = gender
self.first = first
self.last = last
self.status = status
# Using mix-ins to get the desired behavior
class Gender(Field.InitAlways, Field.SqlVarchar):
table = ('F', 'M')
fillNext = -1
@classmethod
def fill(cls, rec):
cls.fillNext += 1
return cls.table[cls.fillNext % 2]
#classes First, Last, & Status are analogous but more complicated
# The descriptors are set up at the bottom of the module like so:
Person.first = Field.Descriptor(First)
Person.gender = Field.Descriptor(Gender)
Person.status = Field.Descriptor(Status)
# Moving along to other stripped supporting code
class Descriptor(object):
def __init__(self, cls, name=None):
self.cls = cls
if name == None:
self.name = cls.__name__.lower()
else:
self.name = name.lower()
def __set__(self, inst, value):
if inst.__dict__.has_key(self.name):
inst.__dict__[self.name] = self.cls(inst, value, True)
else:
inst.__dict__[self.name] = self.cls(inst, value, False)
class InitAlways(str):
def __new__(cls, rec, value, reset):
if reset:
return str.__new__(cls, value)
if value == Empty:
return str.__new__(cls, '')
if value == Fill or value == None: #if value in (None, Fill,
''):
return str.__new__(cls, cls.fill(rec) or '')
return str.__new__(cls, value or '')