Tuple question

Andrew Durdin adurdin at gmail.com
Sat Sep 4 07:27:04 EDT 2004


On Sat, 4 Sep 2004 11:00:30 +0200, Alex Martelli <aleaxit at yahoo.com> wrote:
> 
> Pseudotuples with NAMED (as well as indexed) arguments, as modules stat
> and time now return, may be a different issue.  Not sure why we never
> made declaring such pseudotuples as usertypes as easy as it should be, a
> custom metaclass in some stdlib module shd be enough.  But tuples whose
> items can't be named, just indexed or sliced, just are not a good fit
> for the kind of use case you and Guido use to justify tuple's lack of
> methods, IMHO.

Such "pseudotuples" are easy enough to implement. Since I'm not all
that crash hot with metaclasses, I just made a tuple subclass (see
below). Would a metaclass implementation offer any significant
benefits over a subclass?

class NamedTuple(tuple):
    """Builds a tuple with elements named and indexed.
    
    A NamedTuple is constructed with a sequence of (name, value) pairs;
    the values can then be obtained by looking up the name or the value.
    """

    def __new__(cls, seq):
        return tuple.__new__(cls, [val for name,val in seq])

    def __init__(self, seq):
        tuple.__init__(self)
        tuple.__setattr__(self, "_names", dict(zip([name for name,val
in seq], range(len(seq)))))

    def __getattr__(self, name):
        try:
            return tuple.__getitem__(self, self.__dict__["_names"][name])
        except KeyError:
            raise AttributeError, "object has no attribute named '%s'" % name

    def __setattr__(self, name, value):
        if self._names.has_key(name):
            raise TypeError, "object doesn't support item assignment"
        else:
            tuple.__setattr__(self, name, value)
        
# Example
if __name__ == "__main__":
    names = ("name", "age", "height")
    person1 = NamedTuple(zip(names, ["James", "26", "185"]))
    person2 = NamedTuple(zip(names, ["Sarah", "24", "170"]))
    
    print person1.name
    for i,name in enumerate(names):
        print name, ":", person2[i]


(Submitted to the Cookbook: recipe #303439)



More information about the Python-list mailing list