Class Factories in Python: How?
Warren Postma
embed at geocities.com
Mon May 1 14:35:07 EDT 2000
Suppose I have a base class which handles a Binary Structures, in this case,
a series of Marshalled attributes, stored on disk as a marshalled array (so
it's fast, binary, and no field names are stored with each row).
Each type I want to create a new binary structure, I subclass it, but the
subclassing procedures are getting complex because there are so many
class-variables that need to be initialized. So I decided to try to build a
class factory, like this:
This is a simplified (<100 lines) of something I'm trying to do that is
currently over 500 lines.
Warren
--- code snippet ---
# class factory example
import marshal
import string
def binstruct_lookup(attributes):
"create a dictionary to lookup data row field orderings"
n = 0
dict1 = {}
for n in range(0,len(attributes)):
dict1[attributes[n]] = n
return dict1
class marshalstruct:
"a binary structure handler class - a simplified example"
attributes = [ "a", "b", "c" ] # demo
lookups = binstruct_lookup(attributes)
fieldcount = len(attributes)
def __init__(self):
self.__dict__["values"] =
[None]*self.__class__.__dict__["fieldcount"]
def as_string(self):
return string.join(map(repr,self.__dict__["values"]), ", ")
def marshal(self):
return marshal.dumps(self.values)
def unmarshal(self,binstr):
self.__dict__["values"]= marshal.loads(binstr)
def __getattr__(self,name):
try:
l = self.__class__.__dict__["lookups"][name]
except:
raise LookupError, "invalid field name "+name+" in binstruct."
return self.__dict["values"][l]
def __setattr__(self,name,value):
try:
l = self.__class__.__dict__["lookups"][name]
except:
raise LookupError, "invalid field name "+name+" in binstruct."
self.__dict__["values"][l] = value
# Ugly way to Subclass:
#class marshalstruct2:
# "subclass"
# attributes = [ "d", "e", "f" ]
# lookups = binstruct_lookup(attributes)
# fieldcount = len(attributes)
# when I want to declare a specialization of the above class, I need
# to include all the right things, in the right order, to redefine
# variables at a class scope:
# A Nicer way? Is it possible?
# class factory to specialize the above class given some new attributes to
use:
def marshalstruct_factory(newattributes):
class newclass(marshalstruct):
attributes = newattributes
lookups = binstruct_lookup(attributes)
fieldcount = len(attributes)
return newclass
# fails, attributes = newattributes doesn't work, probably because
# the above class scope doesn't admit the function parameters into its
scope.
#y = marshalstruct_factory(['test1','test2','test3'])
n = marshalstruct()
n.a = "a value"
n.b = "b value"
n.c = "c value"
try:
n.d = "illegal!"
print "Failure: Shouldn't get here!"
except LookupError:
print "Working :illegal attribute name trapped"
print "dump fields separated by commas, as a string:"
print n.as_string()
print "Finished."
More information about the Python-list
mailing list