added POD, ParamSet inheritance check, fixed ParamObj.__repr__

This commit is contained in:
Darren Ranalli 2005-05-25 23:05:29 +00:00
parent 48362bd801
commit d6cb013cc3

View File

@ -982,6 +982,7 @@ class ParamObj:
# END PARAMSET SUBCLASS # END PARAMSET SUBCLASS
def __init__(self, *args, **kwArgs): def __init__(self, *args, **kwArgs):
assert(issubclass(self.ParamSet, ParamObj.ParamSet))
# If you pass in a ParamSet obj, its values will be applied to this # If you pass in a ParamSet obj, its values will be applied to this
# object in the constructor. # object in the constructor.
params = None params = None
@ -1107,7 +1108,138 @@ class ParamObj:
def __repr__(self): def __repr__(self):
argStr = '' argStr = ''
for param in self.ParamSet.getParams(): for param in self.ParamSet.getParams():
argStr += '%s=%s,' % (param, getSetter(self, param, 'get')()) argStr += '%s=%s,' % (param,
repr(getSetter(self, param, 'get')()))
return '%s(%s)' % (self.__class__.__name__, argStr)
"""
POD (Plain Ol' Data)
Like ParamObj/ParamSet, but without lock/unlock/getPriorValue and without
appliers. Similar to a C++ struct, but with auto-generated setters and
getters.
Use POD when you want the generated getters and setters of ParamObj, but
efficiency is a concern and you don't need the bells and whistles provided
by ParamObj.
POD.__init__ *MUST* be called. You should NOT define your own data getters
and setters. Data values may be read, set, and modified directly. You will
see no errors if you define your own getters/setters, but there is no
guarantee that they will be called--and they will certainly be bypassed by
POD internally.
EXAMPLE CLASSES
===============
Here is an example of a class heirarchy that uses POD to manage its data:
class Enemy(POD):
DataSet = {
'faction': 'navy',
}
class Sailor(Enemy):
DataSet = {
'build': HUSKY,
'weapon': Cutlass(scale=.9),
}
EXAMPLE USAGE
=============
s = Sailor(faction='undead', build=SKINNY)
# make two copies of s
s2 = s.makeCopy()
s3 = Sailor(s)
# example sets
s2.setWeapon(Musket())
s3.build = TALL
# example gets
faction2 = s2.getFaction()
faction3 = s3.faction
"""
class POD:
DataSet = {
# base class does not define any data items, but they would
# appear here as 'name': value,
}
def __init__(self, *args, **kwArgs):
self.__class__._compileDefaultDataSet()
if len(args) == 1 and len(kwArgs) == 0:
# extract our dataset from an existing POD instance
obj = args[0]
for name in self.getDataNames():
setattr(self, name, getattr(obj, name))
else:
assert len(args) == 0
if __debug__:
for arg in kwArgs.keys():
assert arg in self.getDataNames()
for name in self.getDataNames():
if name in kwArgs:
setattr(self, name, kwArgs[name])
else:
setattr(self, name, self.getDefaultValue(name))
def setDefaultValues(self):
# set all the default data values on ourself
for name in self.getDataNames():
setattr(self, name, self.getDefaultValue(name))
def makeCopy(self):
# returns a duplicate of this object
return self.__class__(self)
def applyTo(self, obj):
# Apply our entire set of data to another POD
for name in self.getDataNames():
setattr(obj, name, getattr(self, name))
def getValue(self, name):
return getattr(self, name)
# CLASS METHODS
def getDataNames(cls):
# returns safely-mutable list of datum names
cls._compileDefaultDataSet()
return cls._DataSet.keys()
getDataNames = classmethod(getDataNames)
def getDefaultValue(cls, name):
cls._compileDefaultDataSet()
return cls._DataSet[name]
getDefaultValue = classmethod(getDefaultValue)
def _compileDefaultDataSet(cls):
if cls.__dict__.has_key('_DataSet'):
# we've already compiled the defaults for this class
return
# create setters & getters for this class
if cls.__dict__.has_key('DataSet'):
for name in cls.DataSet:
def defaultSetter(self, value, name=name):
setattr(self, name, value)
cls.__dict__[getSetterName(name)] = defaultSetter
def defaultGetter(self, name=name,
default=cls.DataSet[name]):
return getattr(self, name, default)
cls.__dict__[getSetterName(name, 'get')] = defaultGetter
# this dict will hold all of the aggregated default data values for
# this particular class, including values from its base classes
cls._DataSet = {}
bases = list(cls.__bases__)
# bring less-derived classes to the front
mostDerivedLast(bases)
for c in (bases + [cls]):
# make sure this base has its dict of data defaults
c._compileDefaultDataSet()
if c.__dict__.has_key('DataSet'):
# apply this class' default data values to our dict
cls._DataSet.update(c.DataSet)
_compileDefaultDataSet = classmethod(_compileDefaultDataSet)
# END CLASS METHODS
def __repr__(self):
argStr = ''
for name in self.getDataNames():
argStr += '%s=%s,' % (name, repr(getattr(self, name)))
return '%s(%s)' % (self.__class__.__name__, argStr) return '%s(%s)' % (self.__class__.__name__, argStr)
def bound(value, bound1, bound2): def bound(value, bound1, bound2):