Learning Python 1

Tue 08 April 2008 under python

Interesting 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.


Comments