Re: Newbie help- Can multiple instances with multiple names automatically created.
On Mon, 04 Jan 2010 21:27:12 -0800, Nav wrote: > @ Steven > "No, you're confused -- the problem isn't with using the global > namespace. > The problem is that you don't know what names you want to use ahead of > time. " > > Actually I know what the names would be and how I want to use them. You said earlier: "I have a class of let's say empty bottle which can have a mix of two items. I want to create let's say 30 of these objects which will have names based on the 2 attributes (apple juice, beer, grape juice, beer, etc) that I provide from a list." Your description is confusing to me. What on earth is an empty bottle which has a mix of two items in it? Surely that means it's not empty any more? But putting that aside: "All the objects are a mix of (1 of three alcohols) and (1 of 10 juices), so I don't want to go through typing in the names of all the objects (which would be totally stupid)." Right... so your problem isn't that you don't know what the variable names is, but there are too many to comfortably enumerate in the source code. The answer is, again, avoid named variables. Instead of (say): gin_apple_strawberry = Bottle('gin', 'apple') gin_apple_orange = Bottle('gin', 'orange') # etc. again you should use a list or dict: bottles = [] for alcohol in ('gin', 'beer', 'wine'): for fruit in ('apple', 'banana', 'blueberry', 'strawberry', 'orange', 'peach'): bottles.append(Bottle(alcohol, fruit)) for bottle in bottles: process(bottle) -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
"> if yes then: > if using globalnamespace is bad then why does every book or tutorial > about python classes give the above style of assignment as an > example? That's a basic assignment example. It's not a direct manipulation of globals(), like the solution given by Jan, which you seem to feel is the answer. And unless it happens outside of a nested scope like a class or function definition, it's not 'global'. " Thanks for clearing that up Alex. The reason I liked Jan's solution at first glance was that it allowed me to manipulate the objects directly after I created the class. But I am using Shawn's advice now because it lets me abstract, but still allows me to directly manipulate the object if I need to. @ Steven "No, you're confused -- the problem isn't with using the global namespace. The problem is that you don't know what names you want to use ahead of time. " Actually I know what the names would be and how I want to use them. If you look at my example in the beginning you will notice that it creates unique objects with unique names, which anyone who looks at what is being mixed can easily figure out and of course the number and names of objects is directly dependent on the mixed elements. (although perhaps bottle is not the best analogy because the contents can change, which will not change once the object is created.) Having a stable and descriptive naming strategy was important, especially to use the unique object directly, and to not have to go searching where they might be located at any moment, e.g. if they are being moved about as part of other data structures. If anyone has any other thoughts regarding this, I would appreciate them. - Thanks everyone. -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
(You top-posted. It's polite on most newsgroups, and specifically on this one to add your comments *following* the quoted earlier text) Nav wrote: Okay, let me ask another question: When we create instances of objects by doing x = className () are we using globalnamespace? If that line appears at top-level, it uses the global namespace for the symbol x. If it's inside a class, or inside a function, then it uses some other namespace. The risk for globals is mainly that the namespace gets "polluted", or full of unrelated symbols, which sooner or later are going to collide. And this is made much worse if someone is creating such names indirectly, by monkeying with the non-portable constructs such as global(), or by doingfrom mymodule import *There are other risks, but this is a short message. As far as I know, there's very little performance cost for having lots of stuff in globals. It's just bad practice because it frequently leads to bugs. if yes then: if using globalnamespace is bad then why does every book or tutorial about python classes give the above style of assignment as an example? Beginner books keep things simple. Besides the same statement is great if it's in a function. And it's usually a small step for the beginner to start moving stuff from the top-level of the module into named functions. And eventually to functions that are small enough to be maintainable. Second why do we use a dictionary to create something like this? I know how it works, but what is wrong with simply creating instances automatically? Once created the data for the instances is automatically saved in their own space? Why have a round about way using dictionaries? Is there an advantage or does it conflict with something else? What? Automatically where? What's roundabout about dictionaries? Why not have for i in specialList: #I presume it would have to be special, because it can't be a problematic type i = className(whatever) Once you bind a new value to i, it no longer has any relationship to the value which was in specialList. Perhaps you want something like: for i in xrange(len(specialList)): specialList[i] = className(...) which will replace the present values in specialList with instances of className. what are the risks of globalnamespace use You're unnecessarily tying your code to the implementation. and what are the benefits? Absolutely none that using a dictionary doesn't also give you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
On Jan 5, 1:12 pm, Nav wrote: > When we create instances of objects by doing > x = className () > are we using globalnamespace? Well, you're using a namespace, which namespaces its in would depend on the scope in which that assignment occurred. And there's not really a global namespace, only module ones. > if yes then: > if using globalnamespace is bad then why does every book or tutorial > about python classes give the above style of assignment as an > example? That's a basic assignment example. It's not a direct manipulation of globals(), like the solution given by Jan, which you seem to feel is the answer. And unless it happens outside of a nested scope like a class or function definition, it's not 'global'. > Second why do we use a dictionary to create something like this? I > know how it works, but what is wrong with simply creating instances > automatically? If I came across code like this in a joint project I was working on: def somefunc(*someparams): magical_instance_injection() for elem in magically_appearing_collection: We'd have serious words about the readability & maintainability of such code. If the values are important, make a clear set up that places them in a mapped collection, and make it obvious that the collection is how those values are used. Also, you've removed the set up from the place where the values are actually used, meaning I'd have to look at two sets of code to identify the values' names, as well as to confirm that 'some_random_label' _is_ actually one of the instances and not just a value you're using without instantiating. > Once created the data for the instances is > automatically saved in their own space? Why have a round about way > using dictionaries? Because using a dictionary removes the dependency your function has on the injection code, which in turns makes it more flexible for re-use. Let's assume you write your injection function, and call it within every function that uses those objects: def inject_values(): # here be global() manipulations def do_that_thang(): inject_values() ... What if you want to do_that_thang to a separate set of values? With this approach, you'd have to extend like so: def inject_values2(): ... def do_that_thang2(): inject_values2() ... You could, of course, have one inject_values function that accepts a flag and returns the appropriate set of values, but now you're having to modify that function every time the values change. With a dictionary, it's just so much simpler: values1 = dict( a = SomeObject(1), b = AnotherObject(1)... ) values2 = dict( a = SomeObject(2), b = AnotherObject(2)... ) def do_that_thang(values): c = values['a'].thanger(values['b']) ... It's clean, readable and far more easily extensible. It's also far more obvious what you're doing, which you'll really appreciate when you return to the code in a year's time :) -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
On Mon, 04 Jan 2010 19:12:53 -0800, Nav wrote: > Okay, let me ask another question: > > When we create instances of objects by doing > x = className() > are we using globalnamespace? That depends on whether you are doing x = className() inside a function (or class), or in the top level of the program. If I do this: x = 1234 def function(): y = 4567 then x is defined in the global namespace and y is defined in the namespace which is local to function(). > if yes then: > if using globalnamespace is bad then why does every book or tutorial > about python classes give the above style of assignment as an example? No, you're confused -- the problem isn't with using the global namespace. The problem is that you don't know what names you want to use ahead of time. You use assignment like: x = something() when you know the name x when you are writing the code. That way you can write x in the code, and all is good: x = something() print x.method() mydict = {x: -1} assert mydict.keys() == [x] Now, imagine that you didn't know what names you have to use. Say, for example, that you need a variable number of Somethings: a = Something() b = Something() c = Something() d = Something() # I never know when to stop... z = Something() # ... keep going? too far? who knows??? HELP! process(a) process(b) process(c) # when do I stop??? process(x) process(y) # ... That's the wrong way to deal with it. So instead you use a list: mylist = [] # define ONE NAME in the global namespace for i in range(some_number): mylist.append(Something()) # later... for x in mylist: # again, we use ONE name, `x` process(x) A list implicitly maps numbers (the position) to values. If you want to map strings (names) to values, use a dict. Here is an example. Notice we don't know how many players there are, or what their names are: print "Welcome to the game." print "Please enter the name of each player," print "or the word 'STOP' when there are no more players." players = {} i = 1 while True: # loop forever name = raw_input("Name of player %d? " % i) name = name.strip() # get rid of extra whitespace if name.upper() == 'STOP': # we're done break players[name] = NewPlayer() # much later... for name, player in players.items(): print "Welcome, player %s" % name play_game(player) The only downside is that dicts are unordered, so the order of the players is not the same as the order they were entered in. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
Thanks for pointing it out Steve. The blog post doesn't explain it very well. I understand the risk of exec or eval(input). but what are the risks of globalnamespace use and what are the benefits? -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
Okay, let me ask another question: When we create instances of objects by doing x = className () are we using globalnamespace? if yes then: if using globalnamespace is bad then why does every book or tutorial about python classes give the above style of assignment as an example? Second why do we use a dictionary to create something like this? I know how it works, but what is wrong with simply creating instances automatically? Once created the data for the instances is automatically saved in their own space? Why have a round about way using dictionaries? Is there an advantage or does it conflict with something else? Why not have for i in specialList: #I presume it would have to be special, because it can't be a problematic type i = className(whatever) > > > what are the risks of globalnamespace use > > You're unnecessarily tying your code to the implementation. > > > and what are the benefits? > > Absolutely none that using a dictionary doesn't also give you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
On Jan 5, 9:33 am, Nav wrote: > what are the risks of globalnamespace use You're unnecessarily tying your code to the implementation. > and what are the benefits? Absolutely none that using a dictionary doesn't also give you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
Thanks Jan, You read my mind. That is exactly what I needed. Thanks for showing the product function from itertools as well. It seems easier to grasp than the nested loops, I had been using. I noticed chopin.edu.pl. Are you a musician? Nav -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
Nav wrote: > On Jan 4, 4:54 pm, Chris Rebert wrote: >> On Mon, Jan 4, 2010 at 1:32 PM, Shawn Milochik wrote: >>> You could put them in a dictionary with the key being the name, instead of >>> a list. >> To illustrate that for the OP: >> >> name2drink = {} >> for booze in liquors: >> for juice in juices: >> name = juice +" "+booze # or however you're naming them >> drink = Bottle(booze, juice) >> name2drink[name] = drink >> >> #example use >> favorite = name2drink["apple wine"] >> favorite.rating = 9/10 > > typing > favorite = such and such is what I am trying to avoid. > > I want to be able to use the name 'apple_wine' as the variable which > has the object apple wine but not have to do this manually as you did > with favorite. > Why? The example is trying to show you that it's much more sensible (i.e. better controlled, easier to manage, less likely to cause problems) if instead of looking up the names in the global namespace you instead looked them up in a dictionary. This question arises so frequently it should really be a FAQ, but the closest I can come is http://techblog.ironfroggy.com/2007/06/dynamic-hell.html which does at least exercise the necessary arguments. regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/ Holden Web LLC http://www.holdenweb.com/ UPCOMING EVENTS:http://holdenweb.eventbrite.com/ -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
On Jan 4, 2010, at 5:59 PM, Nav wrote: > On Jan 4, 4:54 pm, Chris Rebert wrote: >> On Mon, Jan 4, 2010 at 1:32 PM, Shawn Milochik wrote: >>> You could put them in a dictionary with the key being the name, instead of >>> a list. >> >> To illustrate that for the OP: >> >> name2drink = {} >> for booze in liquors: >> for juice in juices: >> name = juice +" "+booze # or however you're naming them >> drink = Bottle(booze, juice) >> name2drink[name] = drink >> >> #example use >> favorite = name2drink["apple wine"] >> favorite.rating = 9/10 > > typing > favorite = such and such is what I am trying to avoid. > > I want to be able to use the name 'apple_wine' as the variable which > has the object apple wine but not have to do this manually as you did > with favorite. > > > > > Then don't assign a variable to favorite, and just use name2drink["apple wine"]. -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
On Jan 4, 4:54 pm, Chris Rebert wrote: > On Mon, Jan 4, 2010 at 1:32 PM, Shawn Milochik wrote: > > You could put them in a dictionary with the key being the name, instead of > > a list. > > To illustrate that for the OP: > > name2drink = {} > for booze in liquors: > for juice in juices: > name = juice +" "+booze # or however you're naming them > drink = Bottle(booze, juice) > name2drink[name] = drink > > #example use > favorite = name2drink["apple wine"] > favorite.rating = 9/10 typing favorite = such and such is what I am trying to avoid. I want to be able to use the name 'apple_wine' as the variable which has the object apple wine but not have to do this manually as you did with favorite. -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
2010-01-04, 22:54:41 Chris Rebert wrote: name2drink = {} for booze in liquors: for juice in juices: name = juice +" "+booze # or however you're naming them drink = Bottle(booze, juice) name2drink[name] = drink @Nav: ...and if you really desire to have those objects in global (module's) namespace, you can do that: global_namespace = globals() for booze in liquors: for juice in juices: name = '{0}_with_{1}_juice'.format(booze, juice) drink = Bottle(booze, juice) global_namespace[name] = drink # then you have them in module's namespace print(wine_with_apple) wine_with_apple.rating = 0.9 Though in most cases it'd be not necessary. Cheers, *j PS. Another way to express practically the same: from itertools import product globals().update(('{0}_with_{1}_juice'.format(booze, juice), Bottle(booze, juice)) for booze, juice in product(liquors, juices)) -- Jan Kaliszewski (zuo) -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
On Mon, Jan 4, 2010 at 1:32 PM, Shawn Milochik wrote: > You could put them in a dictionary with the key being the name, instead of a > list. To illustrate that for the OP: name2drink = {} for booze in liquors: for juice in juices: name = juice +" "+booze # or however you're naming them drink = Bottle(booze, juice) name2drink[name] = drink #example use favorite = name2drink["apple wine"] favorite.rating = 9/10 Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Newbie help- Can multiple instances with multiple names automatically created.
You could put them in a dictionary with the key being the name, instead of a list. Shawn -- http://mail.python.org/mailman/listinfo/python-list