Factory for Struct-like classes

Matthew Wilson matt at tplus1.com
Thu Aug 14 22:32:18 EDT 2008


On Thu 14 Aug 2008 11:19:06 AM EDT, Larry Bates wrote:
> eliben wrote:
>> Hello,
>> 
>> I want to be able to do something like this:
>> 
>> Employee = Struct(name, salary)
>> 
>> And then:
>> 
>> john = Employee('john doe', 34000)
>> print john.salary

I find something like this useful, especially if any time I tried to
cram in an attribute that wasn't allowed, the class raises an exception.

One way to do it is to make a function that defines a class inside and
then returns it.  See the code at the end of this post for an example.

I couldn't figure out how to do this part though:

>> Employee = Struct(name, salary)

I have to do this instead (notice that the args are strings):

>> Employee = Struct('name', 'salary')

Anyway, here's the code:

    def struct_maker(*args):

        class C(object):
            arglist = args
            def __init__(self, *different_args):

                # Catch too few/too many args.
                if len(self.arglist) != len(different_args):
                    raise ValueError("I need exactly %d args (%s)" 
                        % (len(self.arglist), list(self.arglist)))

                for a, b in zip(self.arglist, different_args):
                    setattr(self, a, b)

            def __setattr__(self, k, v):
                "Prevent any attributes except the first ones."
                if k in self.arglist:
                    object.__setattr__(self, k, v)
                else:
                    raise ValueError("%s ain't in %s" 
                        % (k, list(self.arglist)))

        return C

And here it is in action:

In [97]: Employee = struct_maker('name', 'salary')

In [98]: matt = Employee('Matt Wilson', 11000)

In [99]: matt.name, matt.salary

Out[99]: ('Matt Wilson', 11000)

In [100]: matt.invalid_attribute = 99
---------------------------------------------------------------------------
ValueError: invalid_attribute ain't in ['name', 'salary']


Matt



More information about the Python-list mailing list