On Jun 11, 12:21 pm, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > On Mon, 11 Jun 2007 02:24:51 -0700, Frank Millman wrote: > > Hi all > > > I have a small problem. I have come up with a solution, but I don't > > know if it is a) safe, and b) optimal. > > > I have a class with a number of attributes, but for various reasons I > > cannot assign values to all the attributes at __init__ time, as the > > values depend on attributes of other linked classes which may not have > > been created yet. I can be sure that by the time any values are > > requested, all the other classes have been created, so it is then > > possible to compute the missing values. > > Unless you're doing something like creating classes in one thread while > another thread initiates your instance, I don't understand how this is > possible. >
I was hoping not to have to explain this, as it gets a bit complicated (yes, I have read The Zen of Python ;-), but I will try. I have a class that represents a database table, and another class that represents a database column. When the application 'opens' a table, I create an instance for the table and separate instances for each column. If there are foreign keys, I used to automatically open the foreign table with its columns, and build cross-references between the foreign key column on the first table and the primary key column on the second table. I found that as the database grew, I was building an increasing number of links, most of which would never be used during that run of the program, so I stopped doing it that way. Now I only open the foreign table if the application requests it, but then I have to find the original table and update it with attributes representing the link to the new table. It gets more complicated than that, but that is the gist of it. > >>>> class A(object): > > ... __slots__ = ('x','y','z') > > By using slots, you're telling Python not to reserve space for a __dict__, > which means that your class cannot create attributes on the fly. > I understand that. In fact I was already using slots, as I was concerned about the number of 'column' instances that could be created in any one program, and wanted to minimise the footprint. I have since read some of caveats regarding slots, but I am not doing anything out of the ordinary so I feel comfortable with them so far. > > I use __slots__ to catch any invalid attributes, otherwise I would get > > a 'maximum recursion depth exceeded' error. > > That's the wrong solution to that problem. To avoid that problem, > __getattr__ should write directly to self.__dict__. > Are you saying that instead of self.z = self.x * self.y return getattr(self.name) I should have self.__dict__['z'] = self.x * self.y return self.__dict__[name] I tried that, but I get AttributeError: 'A' object has no attribute '__dict__'. Aslo, how does this solve the problem that 'name' may not be one of the attributes that my 'compute' method sets up. Or are you saying that, if I fixed the previous problem, it would just raise AttributeError anyway, which is what I would want to happen. > > Is this ok, or is there a better way? > > At the interactive Python prompt: > > help(property) > See my reply to Phil - I would use property if there was only one attribute, but there are several. Thanks Frank -- http://mail.python.org/mailman/listinfo/python-list