Learning Python 1
Tue 08 April 2008 by Thejaswi PuthrayaInteresting aspect of Python : 1
Yesterday I learnt an interesting aspect of python called closures.
def a(aa1, aa2=10):
def b(bb1, bb2=aa2):
print aa1, aa2, bb1, bb2
aa1+=100
aa2+=100
return b
>>> a(20)(5)
What is the output?
The answer by intuition would have been 20 10 5 10. The answer however is 120 110 5 10.
I was amazed by this result and wanted to figure out how this works. I ran pdb on this function using
$ python -m pdb test_fn.py
The result of it was:
> /home/theju/test_fn.py(1)<module>()
-> def a(aa1, aa2=10):
(Pdb) s
> /home/theju/test_fn.py(8)<module>()
-> a(20)(5)
(Pdb)
--Call--
> /home/theju/test_fn.py(1)a()
-> def a(aa1, aa2=10):
(Pdb)
> /home/theju/test_fn.py(2)a()
-> def b(bb1, bb2=aa2):
(Pdb) dir()
['aa1','aa2']
(Pdb) s
> /home/theju/test_fn.py(4)a()
-> aa1+=100
(Pdb) dir()
['aa1', 'aa2', 'b']
(Pdb) dir(b)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__',
'__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure',
'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
(Pdb) p b.func_defaults
(10,)
(Pdb) s
> /home/theju/test_fn.py(5)a()
-> aa2+=100
(Pdb)
> /home/theju/test_fn.py(6)a()
-> return b
(Pdb)
--Return--
> /home/theju/test_fn.py(6)a()-><functio...b7c6adbc>
-> return b
(Pdb)
--Call--
> /home/theju/test_fn.py(2)b()
-> def b(bb1, bb2=aa2):
(Pdb)
> /home/theju/test_fn.py(3)b()
-> print aa1, aa2, bb1, bb2
(Pdb)
120 110 5 10
--Return--
> /home/theju/test_fn.py(3)b()->None
-> print aa1, aa2, bb1, bb2
(Pdb)
--Return--
> /home/theju/test_fn.py(8)<module>()->None
-> a(20)(5)
(Pdb)
--Return--
> <string>(1)<module>()->None
(Pdb)
The default parameter values are evaluated when the function definition is executed. See this for more details.
Thanks to Gopi for helping me learn this concept and more.