I wonder if there is a good way to bind local variables in python. Most of my work involves cobbling together short data or text processing scripts with a series of expressions (when python permits), so defining object classes (to use as namespaces) and instantiating them seems a bit much.
So what I had in mind was something like in (common) lisp, where you could do something like
(setq data '(1 2 3))
(setq output
(let ( (x (nth 2 data)) )
x + x))
In python, the best I could come up with is
data = [1,2,3]
output = ((lambda x: x + x)
(data[2]))
These are, of course, very simple examples but might there be something that is as scalable as let or let* in lisp? Are defining classes the best way to go to create a local namespace?...(but feels a little less interactive that way)
Edit: So to further explain the intention (my apologies for vagueness), I want to reduce the use of global variables. So in the case above, I meant to use the extraction operator as a general case of any type of operation that might not want to be repeated. For instance, one might write either
output = data[2] + data[2]
or
x = data[2]
output = x + x
del x
to accomplish the same result. In essence, if the desired operation on 'data' is more complicated then getting the second item, I wouldn't want to type it out multiple times, or let the computer compute the value of the same expression more times than necessary. So in most cases one would assign the result of the operation, in this case, data[2], or operator.itemgetter(2)(data), to some variable in the global space, but I have an aversion to leaving variables around in the global space if they were only necessary to store intermediate values in a computation... hence the use of the 'del' command immediately afterwards. Defining a local environment or namespace and binding intermediate results to local variables would be an ideal alternative.
I can only second Lennart and Daniel - Python is not Lisp, and trying to write language X into language Y is usually inefficient and frustrating at best.
First point: your example code
data = [1,2,3]
output = ((lambda x: x + x)
(data[2]))
would be much more readable as:
data = [1, 2, 3]
output = (lambda x=data[2] : x +x)()
but anyway, in this concrete case, using a lambda is total overkill, overcomplexificated, and mostly inefficient. A braindead
output = data[2] + data[2]
would JustWork(tm) !-)
Now wrt/ to local bindings / namespaces, the usual solution is to use... functions - eventually nested. While 100% object (as in "everything is an object"), Python is not pure object, and plain functions are just fine. FWIW, even for "scripts", you should put your logic in a function then call it - function's local namespace access is faster than "global" (really: module level) namespace access. The canonical pattern is
import whatever
def some_func(args):
code_here
def some_other_func(args)
code_here
def main(args):
parse_args
some_func(something)
some_other_func(something_else)
return some_exit_code
if __name__ == '__main__'
import sys
sys.exit(main(sys.argv))
Note also that nested functions can also access the enclosing namespace, ie
def main():
data = [1, 2, 3]
def foo():
x = data[2]
return x + x
print foo()
data = [4, 5, 6]
print foo()
# if you want the nested function to close over its arguments:
def bar(data=data):
x = data[2]
return x + x
print bar()
data = [7, 8, 9]
print bar()
HTH
It's a bit unclear what you are asking, bit I'll try to answer anyway:
You bind variables to names with = in Python. So your data = [1,2,3]
binds the list [1,2,3]
to the name data
.
You can create local namespaces with classes and functions/methods.
The closest you get so something as powerful as let
is probably def
and lambda
. Python is (despite where some people try to tell you) not Lisp, and not particularly functional, so you will have to adapt your mindset a bit.
Update: Ah, I see what you mean now.
All variables are pretty much local in Python. The nearest you get to global variables are variables defined in module space, because you can access them with from <module> import <variable>
. You also can access them from wherever in the module, but not modify them (unless you say that you want to modify them with the global
keyword. Anything you define in a function/method or class definition, will only be accessible from that namespace.
So in short: you don't have to worry about the things you worry about now. Python takes care of it for you. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With