structs in python

Christos TZOTZIOY Georgiou DLNXPEGFQVEB at spammotel.com
Fri Dec 27 03:52:46 EST 2002


On Mon, 8 Jul 2002 08:09:20 +0200, rumours say that Gerhard Häring
<gerhard.haering at gmx.de> might have written:

>* Christopher A. Craig <list-python at ccraig.org> [2002-07-08 01:22 -0400]:
>> "Kevin O'Connor" <kevin at koconnor.net> writes:
>> 
>> > What if a syntax like the following were permitted:
>> > >>> p = ( .x = 10, .y = 11, .color = 'blue')
>> > >>> print p.x
>> > 10
>> > >>>
>> 
[snip suggesting using a dict]
> 
>I prefer tiny data-only classes. These can be used exactly like a a
>struct.

I know this will be too late (limited time in the last few months made
me skip group browsing...), and perhaps Alex Martelli's solution is more
generic, but the solution I have come to for my needs might be useful to
others too.
I sometimes need lots of struct-like tuples (immutable structs of
various "types" with named access to their members), and here follows
the module I named "TupleStruct.py", defining a class-factory named
TupleStructType.  Check at the bottom for an example usage.

"""TupleStructType: a metaclass to create classes based on tuple
with named access to the tuple members"""
# (c) tzot at sil-tec.gr 20020914
# License: Public Domain
__version__= (1, 0, 0)
import sys
if sys.hexversion<0x02030000:
    from tzot.future import enumerate # simulate 2.3 enumerate
# to simulate enumerate for python <2.3, use the following
# function:
#def enumerate(seq):
#   _index= 0
#   for _itm in seq:
#       yield (_index, _itm)
#       _index+= 1


class TupleStructType(type):
    """Create a tuple derived class with named members"""

    def __new__(cls, members):
        """Create a new class with the members specified as space
separated words in a string"""
        member_list= members.split()
        attributes= {}

        def new_cls_new(new_cls, *data):
            return tuple.__new__(new_cls, data)
        attributes['__new__']= new_cls_new
        attributes['__slots__']= () # important, so the new class won't
have a dict

        # factory for the property get functions
        def property_factory(index):
            def property_get(self):
                try:
                    value= self[index]
                except IndexError:
                    value= None
                return value
            return property_get

        # getstate, setstate for pickling
        def my_getstate(self):
            return tuple(self)
        attributes['__getstate__']= my_getstate
        def my_setstate(self, data):
            self= self.__class__(*data)
        attributes['__setstate__']= my_setstate

        # create the property get functions
        for index, member in enumerate(member_list):
            attributes[member]= property(property_factory(index))
        attributes['__doc__']="TupleStruct(%s)" % ','.join(member_list)

        cls_name= "TplStr_" + '_'.join(member_list)
        new_cls= type.__new__(cls, cls_name, (tuple,), attributes)
        globals()[cls_name]= new_cls # add the name to the module for
pickle use
        return new_cls

if __name__=="__main__":
    Person= TupleStructType("name city age") # Person is a class now
    person= Person("Chris", "Athens", 30)
    tpl= ("Chris", "Athens", 30)
    person2= Person(*tpl)
    if person[0]!=person.name or person[1]!=person.city \
            or person[2]!=person.age:
        print "named access failed"
    if person!=tpl:
        print "comparison to tuple failed"
    if person!=person2:
        print "comparison to other person failed"
    person0= Person("Lena")
    if person0.age is not None:
        print "missing members are not None"
    print person0.__class__
    print dir(person0)


-- 
TZOTZIOY, I speak England very best,
Real email address: 'dHpvdEBzaWwtdGVjLmdy\n'.decode('base64')



More information about the Python-list mailing list