Properties and Objects...
George V. Neville-Neil
gnn at neville-neil.com
Mon Sep 24 06:30:50 EDT 2007
At Sun, 23 Sep 2007 19:01:04 -0300,
Gabriel Genellina wrote:
>
> En Sat, 22 Sep 2007 15:06:38 -0300, George V. Neville-Neil
> <gnn at neville-neil.com> escribi�:
>
> > I have been trying to switch this over to using properties, which seem
> > at first glance to be cleaner, but which I am having a lot of problems
> > with. In particular I want to add a property to an object, not a
> > class. The field list in a class is actually relatively static but I
> > wind up with ugly code like:
> >
> > class ethernet(pcs.Packet):
> > """Ethernet"""
> > __layout__ = pcs.Layout()
> > _map = ethernet_map.map
> > src = pcs.StringField("src", 48)
> > dst = pcs.StringField("dst", 48)
> > type = pcs.Field("type", 16)
> >
> > def __init__(self, bytes = None, timestamp = None):
> > """initialize an ethernet packet"""
> >
> > src = pcs.StringField("src", 48)
> > dst = pcs.StringField("dst", 48)
> > type = pcs.Field("type", 16)
> >
> > pcs.Packet.__init__(self, [dst, src, type], bytes = bytes)
> > self.description = inspect.getdoc(self)
>
> You don't have to repeat the fields:
>
> pcs.Packet.__init__(self, [self.dst, self.src, self.type], bytes
> = bytes)
>
Actually that calls the __get__ method of the descriptor, which is not
what I want, I need a list of the objects in the layout.
> does the same thing.
> And you can remove self.description=... and use (at the class level):
> description = __doc__
> or:
> description = property(lambda self: self.__doc__)
> to automatically enable subclases to share the definition
Ah, that's very cool, thanks.
> One could say that the field order is important so I'd finally write it as:
>
> class ethernet(pcs.Packet):
> """Ethernet"""
> __layout__ = pcs.Layout()
> _map = ethernet_map.map
> src = pcs.StringField("src", 48)
> dst = pcs.StringField("dst", 48)
> type = pcs.Field("type", 16)
> _fields = [dst, src, type]
> description = property(lambda self: self.__doc__)
>
> def __init__(self, bytes = None, timestamp = None):
> """initialize an ethernet packet"""
>
> pcs.Packet.__init__(self, self._fields, bytes = bytes)
>
> > and assigning the properties at class time means that it's hard to
> > have variations, packets with the same name but with slightly varying
> > field lists.
>
> This is the part I don't understand. Can't you define a new class, in case
> you want a different field list? Using the above class:
>
> class ethernet_modified(ethernet):
> """Modified ethernet class"""
> added_field = pcs.StringField("whatever", 16)
> _fields = [dst, src, type, added_field]
>
> And it doesn't even requiere an __init__ method
>
Yes, I could and probably should define different objects.
> > So, is there a way to assign a property to an object, like this:
> >
> > def __init__(....
> > self.src = property()
> >
> > or something like that?
>
> I'd use different classes for different kind of objects.
>
> > And, failing that, is there a clean way to modify the class in it's
> > __init__() method so I don't have to call the Field objects twice,
> > once for the property effect and once to put into the list in the base
> > Packet class?
>
> I think my example above does what you want.
Other than the fact that I need the list of Field objects in the
layout, and not the values, yes. Of course that's the hard part.
Thanks,
George
More information about the Python-list
mailing list