[Python-ideas] Syntax for making stuct / record / namedtuples

Nick Coghlan ncoghlan at gmail.com
Wed Oct 21 14:24:58 CEST 2009


Eero Nevalainen wrote:
> Since the fields are already defined in the function signature, I'd
> prefer to not repeat myself and write something like this:
> 
> def my_factory_function(a, b, c):
>     args = locals()
>     # input checking
>     return namedtuple('MyTypeName', args)
> This would perceivably be possible, if locals() returned an OrderedDict
> and an appropriate namedtuple factory function was added.

Not really necessary though.

(2.x example - replace func_code with __code__ for 3.x. Alternatively,
just use the inspect module instead of coding it directly)

>>> from collections import namedtuple
>>> def argnames(f):
...   return f.func_code.co_varnames[:f.func_code.co_argcount]
...
>>> def factory(a, b, c):
...   return namedtuple('MyClass', argnames(factory))(a, b, c)
...
>>> argnames(factory)
('a', 'b', 'c')
>>> x = factory(1, 2, 3)
>>> x
MyClass(a=1, b=2, c=3)

That's pretty wasteful though, since you're creating a new type every
time through the function. Subclassing gives you an alternative way of
checking the argument validity without ever repeating the list of field
names:

>>> def check_args(a, b, c):
...   # Check args, raise exceptions, etc
...   pass
...
>>> class MyClass(namedtuple('MyClass', argnames(check_args))):
...   def __new__(*args):
...     check_args(*args[1:])
...     return super(args[0], MyClass).__new__(*args)
...
>>> y = MyClass(1, 2, 3)
>>> y
MyClass(a=1, b=2, c=3)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------



More information about the Python-ideas mailing list