Help with dynamic attributes.
Hi all, I was writing a simple class when I get a strange error message that I can't understand. Hopefully someone could help me here. My class's init method takes a list of lists as input argument and I'd like to create several attributes each one referencing one item of the passed list. Easy-of-use arguments has led me to call these attributes as x0, x1, x2 and so on. In order to get as many attributes as the number of items of the passed list dynamically defined I wrote the following code: class foo(object): def __init__(self, list_of_lists): self.lol = list(list_of_lists) for i in range(len(list_of_lists)): exec 'self.x%d = self.lol[%d]' % (i, i) self.shape = tuple(len(item) for item in self.lol) As soon as I try to import the module in which this class is defined I get the following error message: SyntaxError: unqualified exec is not allowed in function '__init__' it contains a nested function with free variables (module_name.py, line 49) After a little bit of trials and errors I found that if I comment out the line self.shape = tuple(len(item) for item in self.lol) or I rewrote the for cycle as follows: for i in range(len(list_of_lists)): exec 'self.x%d = self.lol[%d]' % (i, i) in locals() the error disappears and the code works as expected. What it is even more strange to me is that if I replace the generator expression statement (that defines self.shape) with an explicit for-loop the error message doesn't come in and the code works flawlessly. I really can't understand why it happens and I'm wondering what it's going on here behind the scene. Any explanation? Any better way to get the same attributes I got with the exec statement? Thanks in advance, Andrea -- http://mail.python.org/mailman/listinfo/python-list
Re: Help with dynamic attributes.
Mr.Rech wrote: class foo(object): def __init__(self, list_of_lists): self.lol = list(list_of_lists) for i in range(len(list_of_lists)): exec 'self.x%d = self.lol[%d]' % (i, i) self.shape = tuple(len(item) for item in self.lol) generator expressions are anonymous functions, and the self in that line is a free variable (that is, it belongs to an outer scope). Python uses static analysis to identify free variables, and that doesn't mix well with exec. Any better way to get the same attributes I got with the exec statement? use setattr(self, name, value) /F -- http://mail.python.org/mailman/listinfo/python-list
Re: Help with dynamic attributes.
I would have sworn that it had been a better way to get it. Thanks a lot, Andrea -- http://mail.python.org/mailman/listinfo/python-list
Re: Help with dynamic attributes.
Mr.Rech a écrit : (snip) My class's init method takes a list of lists as input argument and I'd like to create several attributes each one referencing one item of the passed list. Easy-of-use arguments has led me to call these attributes as x0, x1, x2 and so on. This is a very wrong design IM(ns)HO. A 'has-many' semantic is better expressed by a multivalued attribute (ie : list, tuple or dict) than by an undefined number of monovalued attributes. Also, the way you're trying to implement it, you will loose sync between individual monovalued attributes and the list of lists. My 2 cents -- http://mail.python.org/mailman/listinfo/python-list
Re: Help with dynamic attributes.
Mr.Rech [EMAIL PROTECTED] writes: Hi all, I was writing a simple class when I get a strange error message that I can't understand. Hopefully someone could help me here. My class's init method takes a list of lists as input argument and I'd like to create several attributes each one referencing one item of the passed list. Why? You save all of two characters per reference over doing a simple self.x = list(self.lol) mike -- Mike Meyer [EMAIL PROTECTED] http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list