Python
does provide another useful feature called Closures. A Closure is a function object
that remembers values in the enclosing scopes regardless of whether those
scopes are still present in memory. Closures are functions that inherit
variables from their enclosing environment. If you have ever written a function
that returned another function, you probably may have used closures even
without knowing about them.
Consider
a sample Python code,
def
print_hello(msg):
def printt(var):
print msg * var
printt(4)
print_hello("hello")
Once
you execute the code we can see,
[djas999@vx181d
imp]$ python hello.py
Hellohellohellohello
Python
provides some additional facilities that most other high level languages do not
provide. One such facility is to assign a function to a variable. The same
above snippet can be written as
[djas999@vx181d
imp]$ cat hello.py
def
print_hello(msg):
def printt(var):
print msg * var
return printt
hello=print_hello("hello")
hello(5)
In
the above code we have returned the print(var) method and we created a variable
hello which now contains the print_hell(“hello”) method. Then we can invoke the
function by calling the variable like hello(5).
The
print_hello() function was called with hello and retuned function was bounded
to another name called "hello" . Now the closures come in action.
Even though the print_hello(“hello”) method execution is completed and removed
from scope,on calling hello(), the message was still remembered .This technique
by which some data ("Hello") gets attached to the code is called
closure in Python.
The main point is that the value from
the top function is remembered in the sub function even though the scope of the
function is complete or the function is removed from the namespace. This is
called Closure.
Function
attributes are available in func_closure in python < 3.X and __closure__ in
python > 3.X save the free variables that are being passed from one scope to
another.
Now
if we add the func_closure code, we can see
[djas999@vx181d
imp]$ cat hello.py
def
print_hello(msg):
def printt(var):
print msg * var
return printt
hello=print_hello("hello")
hello(5)
print
hello.func_closure
[djas999@vx181d
imp]$ python hello.py
hellohellohellohellohello
['__class__',
'__cmp__', '__delattr__', '__doc__', '__format__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']
[djas999@vx181d imp]$ cat hello.py
import
os
def
print_hello(msg):
def printt(var):
print msg * var
return printt
hello=print_hello("hello")
hello(5)
print
dir(hello.func_closure[0])
print
hello.func_closure[0].cell_contents
The
above snippet also gives us the value of the variable as “hello” if we run the
code.
Not
closure
def
make_printer(msg):
...
def printer():
...
pass
...
return printer
...
>>> printer = make_printer('Foo!')
>>> printer.func_closure
If
a function does not use free variables it doesn't form a closure.
No comments :
Post a Comment