En Mon, 05 May 2008 20:34:32 -0300, John Schroeder <[EMAIL PROTECTED]>
escribió:
Basically I have some classes like this:
###############################################################################
# 0x01: ModeCommand
###############################################################################
class ModeCommand:
"""This is the Mode Command Packet class."""
def __init__(self, mode, command, id=0x01):
"""The unspecial init function."""
self.mode = mode
self.command = command
self.id = id
def RawData(self):
return [self.id, self.mode, self.command]
def __getitem__(self, index):
"""[] operator (read): indexes from the byte data."""
return self.RawData()[index]
def __str__(self):
"""Print a nice thing."""
string = "Mode = %d\n" % self.mode + \
"Command = %d\n" % self.command + \
"ID = %d\n\n" % self.id
return string
###############################################################################
# 0x02: CallRequest
###############################################################################
class CallRequest:
"""This is the Call Request Packet class. (Look familiar?)"""
def __init__(self, service_number, id=0x02):
"""The unspecial init function."""
self.service_number = service_number
self.id = id
def RawData(self):
return [self.id, self.service_number]
def __getitem__(self, index):
"""[] operator (read): indexes from the byte data."""
return self.RawData()[index]
def __str__(self):
"""Print a nice thing."""
string = "Service Number = %d\n" % self.service_number + \
"ID = %d\n\n" % self.id
return string
###############################################################################
# Test Code
###############################################################################
x = ModeCommand(mode=1, command=0)
print x[:]
print x
y = CallRequest(service_number=2001)
print y[:]
print y
Which is ok but I had to do this over 100 times. It is difficult to
maintain and no one else can understand what the heck I did here. So I
was
trying to look a metaclasses to do something fancy like this:
You don't need a metaclass, nor a class factory. You only need a base
class.
__getitem__ is the same on both classes, and presumably on all: move it to
the base class.
And the only difference between both versions of __init__, RawData and
__str__ is the name and order of the attributes: let's make them a
parameter, a class attribute. The default id attribute may be a class
attribute too.
So in principle, if you have the right base class, the subclasses could be
defined as simply as:
class ModeCommand(Base):
"""This is the Mode Command Packet class."""
parameters = "mode command id".split()
id = 0x01
class CallRequest(Base):
"""This is the Call Request Packet class. (Look familiar?)"""
parameters = "service_number id".split()
id = 0x02
and that's all. Now we have to write the Base class:
class Base(object):
parameters = None # redefined in all subclasses
id = None
def __init__(self, **kw):
assert self.parameters is not None # must be redefined
for name in kw:
if name in self.parameters:
setattr(self, name, kw[name])
else:
raise NameError, "unknown parameter: %s" % name
assert self.id is not None # must be redefined
def RawData(self):
return [getattr(self, name) for name in self.parameters]
def __getitem__(self, index):
return self.RawData()[index]
def __str__(self):
return '\n'.join(
["%s = %r" % (name, getattr(self, name))
for name in self.parameters])
py> x = ModeCommand(mode=1, command=0)
py> print x[:]
[1, 0, 1]
py> print x
mode = 1
command = 0
id = 1
py> y = CallRequest(service_number=2001, id=13)
py> print y[:]
[2001, 13]
py> print y
service_number = 2001
id = 13
(the convention is to use lowercase names for attributes: rawdata instead
of RawData)
--
Gabriel Genellina
--
http://mail.python.org/mailman/listinfo/python-list