On 01/02/2014 02:35 PM, Steven D'Aprano wrote:
On Thu, Jan 02, 2014 at 12:57:49PM +0100, Liam Marsh wrote:
hello,here is my idea: var(): input var name (str), outputs var value example:
count1=1.34 var('count',1) 1.34thank you and have a nice day!
Hello Liam, and welcome! Is this your first post here? I don't recall seeing your name before.
I'm afraid I don't quite understand your example above. The "thank you and have a nice day" confuses me, I don't understand where it comes from. Also, I'm not sure why you define a variable count1 = 1.34, and then pass "count", 1 as two separate arguments to the function. So I'm going to try to guess what your idea actually is, or at least what I think is reasonable, if I get it wrong please feel free to correct me.
You want a function, var(), which takes a single argument, the name of a variable, and then returns the value of that variable. E.g. given a variable "count1" set to the value 1.34, the function call:
var("count1")
will return 1.34.
Is this what you mean?
If so, firstly, the name "var" is too close to the existing function "vars". This would cause confusion.
Secondly, you can already do this, or at least *almost* this, using the locals() and globals() functions. Both will return a dict containing the local and global variables, so you can look up the variable name easily using locals() and standard dictionary methods:
py> count1 = 1.34 py> locals()['count1'] 1.34 py> locals().get('count2', 'default') 'default'
The only thing which is missing is that there's no way to look up a variable name if you don't know which scope it is in. Normally name resolution goes:
locals nonlocals globals builtins
You can easily look up a local name, or a global name, using the locals() and globals() function. With just a tiny bit more effort, you can also look in the builtins. But there's no way that I know of to look up a nonlocal name, or a name in an unspecified scope. Consequently, this *almost* works:
def lookup(name): import builtins for namespace in (locals(), globals(), vars(builtins)): try: return namespace[name] except KeyError: pass raise NameError("name '%s' not found" % name)
except for the nonlocal scope.
I would have guessed that you could get this working with eval, but if there is such a way, I can't work it out.
I think this would make a nice addition to the inspect module. I wouldn't want to see it as a builtin function, since it would encourage a style of programming which I think is poor, but for those occasional uses where you want to look up a variable from an unknown scope, I think this would be handy.
I once used a direct try ... except NameError, which automagically looks up in the whole scope cascade: i = 1 try: x = i except NameError: x = None # no "lookup-able" symbol 'j' try: y = j except NameError: y = None print (x,y) # ==> 1 None Pretty practicle. [Actually, I've never had any need for this in real python code, it was to simulate variable strings (implanted as eg "Hello, {username}!"), which requires variable lookup by name, itself variable. But python already has the final feature (even twice, with % or format).] Denis