Thanks Steve for your help (and the humor). I can see that it was a bad idea with your explanation. (I just didn't want to type all that extra code :-))
I am going to re-write it using your dict approach - that looks a lot cleaner Thanks! Chris Hare ch...@labr.net http://www.labr.net On Dec 1, 2011, at 11:25 PM, Steven D'Aprano wrote: > Chris Hare wrote: > >> What I am trying to do is create a set of variables based upon the table >> names in the table variables. I have similar code which dynamically >> creates check buttons and the associated grid. But I suspect those won't >> work either. >> What have I got wrong? > > Everything! <wink> > > Seriously though, your basic approach is the wrong approach. Don't try to > create dynamic variables like that. Suppose you succeed: > > varName = 'x' # read from a file, or something > exec('%s = 1' % varName) # creates the variable x > > Great. Now you have a variable x. Later on, how do you use it? > > # much later on in your code... > y = x + 1 > > But that won't work, because you don't know that it's called x! If you knew > it was called x, you would have just written x = 1 early and not needed exec. > > Working with dynamic variable names is a pain and a nightmare. Don't do it. > Even if you succeed, you are making a rod for your own back: maintaining such > code is horrible. > > The right way to do this is almost always to use a data structure that maps > names to values, in other words, a dict. > > varName = 'x' # read from a file, or something > data = {varName: 1} > # ... > # much later > y = data[varName] + 1 > > > In this case, something like: > > > names = ["Farm", "Animals", "AnimalTypes", "Users", "Roles", > "Capabilities", "Pedigrees", "ChipMaker", "Owner", "Providers", > "RegistryL" > ] > self.cbReadTable = {} > for name in names: > self.cbReadTable[name] = IntVar() > > > And that's it. Instead of retrieving instance.cbFarmRead, use > instance.cbReadTable['Farm']. > > If you absolutely must use instance attributes, perhaps because you think > you're writing Javascript <wink>, then: > > for name in names: > name = 'cb' + name 'Read' > setattr(self, name, IntVar()) > > > And best of all, you avoid the code injection security vulnerability where > somebody manages to fool your code into using a list of table names like: > > names = ["Farm", "Animals", "AnimalTypes", "Users", "Roles", > "Capabilities", "Pedigrees", > "ChipMaker=1;import os;os.system('echo you are pwned rm-rf haha');", > "Owner", "Providers", "RegistryL" > ] > > > Hope your backups are really good. > > http://xkcd.com/327/ > > > > -- > Steven > > _______________________________________________ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor
_______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor