Syntax for making stuct / record / namedtuples

From the (creative) laziness department: Whenever my module A needs to pass a lot of data to module B, I find myself making a factory function in module B for creating the datastructures def my_factory_function(a, b, c): # input checking res.a = a res.b = b res.c = c return res I believe this is fairly common. 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. related discussion is in: http://kbyanc.blogspot.com/2007/07/python-aggregating-function-arguments.htm... http://code.activestate.com/recipes/500261/ Does this seem familiar or useful to anyone besides me? -- Eero Nevalainen

I would also appreciate a faster way to do the boilerplate in an __init__ of saying self.arg1 = arg1, self.arg2 = arg2, etc. But what would be the global implications of changing locals() to an odict? Is that backwards compatible? If not, perhaps we could add a new builtin, say "olocals()" instead? —Carl

2009/10/21 Carl Johnson <cmjohnson.mailinglist@gmail.com>:
I would also appreciate a faster way to do the boilerplate in an __init__ of saying self.arg1 = arg1, self.arg2 = arg2, etc.
There was a discussion on c.l.p and I wrote a recipe for that: http://code.activestate.com/recipes/551763/ -- Arnaud

Carl Johnson schrieb:
locals() does not only return function arguments. You need to specify the order of that ordered dictionary for such a function precisely. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

Eero Nevalainen schrieb:
Sorry, I don't understand *at all* what you are proposing here. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

2009/10/21 Eero Nevalainen <eero.nevalainen@indagon.com>
The C# syntax for this (anonymous types new in C# 3.0) is: var obj = new { prod.Color, prod.Price } C# creates what is effectively a named tuple parsing the field names from the way you construct it. The closest Python syntax would be something like: obj = {Color=foo, Price=bar} Or as we seem to be overloading curly braces a great deal now, how about: obj = (Color=foo, Price=bar) All the best, Michael

Eero Nevalainen wrote:
Does this seem familiar or useful to anyone besides me?
Python 3, metaclasses and __prepare__ (aka PEP 3115). The performance of the local function namespace is critical to Python's speed characteristics, so slowing it down would not be appreciated (and odicts definitely *are* slower than regular dicts due to the extra checks involved). The performance of class namespaces during definition is much less critical however, and OrderedDict was added in part so that people could easily return it from __prepare__ methods without having to write one themselves. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------

On Wed, Oct 21, 2009 at 12:13 PM, Eero Nevalainen <eero.nevalainen@indagon.com> wrote:
You can override the __new__ method in your type: class Foo(namedtuple('Foo', 'a b c')): def __new__(cls, a, b, c): # input validation and/or adaptation a = int(a) b = float(b) c = list(c) return super(Foo,cls).__new__(cls,a,b,c)
Foo(1, 2, 'xyz') Foo(a=1, b=2.0, c=['x', 'y', 'z'])
It's not perfect (the super call is ugly, in 2.x at least) but it works. George

Eero Nevalainen wrote:
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)
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:
Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------

I would also appreciate a faster way to do the boilerplate in an __init__ of saying self.arg1 = arg1, self.arg2 = arg2, etc. But what would be the global implications of changing locals() to an odict? Is that backwards compatible? If not, perhaps we could add a new builtin, say "olocals()" instead? —Carl

2009/10/21 Carl Johnson <cmjohnson.mailinglist@gmail.com>:
I would also appreciate a faster way to do the boilerplate in an __init__ of saying self.arg1 = arg1, self.arg2 = arg2, etc.
There was a discussion on c.l.p and I wrote a recipe for that: http://code.activestate.com/recipes/551763/ -- Arnaud

Carl Johnson schrieb:
locals() does not only return function arguments. You need to specify the order of that ordered dictionary for such a function precisely. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

Eero Nevalainen schrieb:
Sorry, I don't understand *at all* what you are proposing here. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

2009/10/21 Eero Nevalainen <eero.nevalainen@indagon.com>
The C# syntax for this (anonymous types new in C# 3.0) is: var obj = new { prod.Color, prod.Price } C# creates what is effectively a named tuple parsing the field names from the way you construct it. The closest Python syntax would be something like: obj = {Color=foo, Price=bar} Or as we seem to be overloading curly braces a great deal now, how about: obj = (Color=foo, Price=bar) All the best, Michael

Eero Nevalainen wrote:
Does this seem familiar or useful to anyone besides me?
Python 3, metaclasses and __prepare__ (aka PEP 3115). The performance of the local function namespace is critical to Python's speed characteristics, so slowing it down would not be appreciated (and odicts definitely *are* slower than regular dicts due to the extra checks involved). The performance of class namespaces during definition is much less critical however, and OrderedDict was added in part so that people could easily return it from __prepare__ methods without having to write one themselves. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------

On Wed, Oct 21, 2009 at 12:13 PM, Eero Nevalainen <eero.nevalainen@indagon.com> wrote:
You can override the __new__ method in your type: class Foo(namedtuple('Foo', 'a b c')): def __new__(cls, a, b, c): # input validation and/or adaptation a = int(a) b = float(b) c = list(c) return super(Foo,cls).__new__(cls,a,b,c)
Foo(1, 2, 'xyz') Foo(a=1, b=2.0, c=['x', 'y', 'z'])
It's not perfect (the super call is ugly, in 2.x at least) but it works. George

Eero Nevalainen wrote:
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)
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:
Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
participants (8)
-
Arnaud Delobelle
-
Carl Johnson
-
Eero Nevalainen
-
Georg Brandl
-
George Sakkis
-
Mark Tolonen
-
Michael Foord
-
Nick Coghlan