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