.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/basics/nested_functions.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_basics_nested_functions.py: ======================= 1.15 nested functions ======================= .. GENERATED FROM PYTHON SOURCE LINES 8-9 A nested function is a function inside a function. .. GENERATED FROM PYTHON SOURCE LINES 12-23 .. code-block:: default def percent(x, n): def number(): factor = n / 100 print(x * factor) number() percent(120, 10) .. rst-class:: sphx-glr-script-out .. code-block:: none 12.0 .. GENERATED FROM PYTHON SOURCE LINES 24-26 It is pertinent to note that the function ``number`` was able to use the variable ``x`` and ``n`` which are from outer function ``percent``. .. GENERATED FROM PYTHON SOURCE LINES 28-30 In following example, the inner function is making use of variable ``factor`` which is defined inside the outer function ``percent``. .. GENERATED FROM PYTHON SOURCE LINES 30-42 .. code-block:: default def percent(x, n): factor = n / 100 def number(xx): print(xx * factor) number(x) percent(120, 10) .. rst-class:: sphx-glr-script-out .. code-block:: none 12.0 .. GENERATED FROM PYTHON SOURCE LINES 43-44 It is more clear now that inner function can make use of variables from outer functions. .. GENERATED FROM PYTHON SOURCE LINES 46-47 In following example, the outer function returns the inner function which can be used later on. .. GENERATED FROM PYTHON SOURCE LINES 50-63 .. code-block:: default def percent(n): factor = n / 100 def number(xx): print(xx * factor) return number ten_percent = percent(10) # execution of percent is finished ten_percent(150) # variable `factor` is still remembered/used .. rst-class:: sphx-glr-script-out .. code-block:: none 15.0 .. GENERATED FROM PYTHON SOURCE LINES 64-70 When we called the ``percent`` function, it returned the inner function ``number``. We assigned this inner function to a variable ``ten_percent``. Now we can use this variable to call the inner function. The inner function still remembers the value of ``factor`` which was set when we called the outer function ``percent``. Thus when we call ``ten_percent(150)``, it is actually calling the inner function ``number`` with the value of ``factor`` set to 0.1. .. GENERATED FROM PYTHON SOURCE LINES 70-74 .. code-block:: default two_percent = percent(2) two_percent(150) .. rst-class:: sphx-glr-script-out .. code-block:: none 3.0 .. GENERATED FROM PYTHON SOURCE LINES 75-78 .. code-block:: default ten_percent(300) # factor is 0.1 .. rst-class:: sphx-glr-script-out .. code-block:: none 30.0 .. GENERATED FROM PYTHON SOURCE LINES 79-86 The variable ``factor`` is linked with the inner function and so with ``ten_percent`` and ``two_percent``. Both ``ten_percent`` and ``two_percent`` have different values of ``factor`` associated with them. It is worth noting that, even when the execution of function ``percent`` is finished, its variable ``factor`` is still remembered by ``ten_percent`` and ``two_percent``.We can find out which value of ``factor`` is associated with ``ten_percent`` and which value is associated with ``two_percent``. .. GENERATED FROM PYTHON SOURCE LINES 88-91 .. code-block:: default ten_percent.__closure__[0].cell_contents .. rst-class:: sphx-glr-script-out .. code-block:: none 0.1 .. GENERATED FROM PYTHON SOURCE LINES 92-95 .. code-block:: default two_percent.__closure__[0].cell_contents .. rst-class:: sphx-glr-script-out .. code-block:: none 0.02 .. GENERATED FROM PYTHON SOURCE LINES 96-99 Although we finished execution of function ``percent`` in previous cell, but upon executing ``ten_percent(300)``, the function ``number``, still remembers that what ``factor`` it has to multiply with. In this way we link a certain data with a function. .. GENERATED FROM PYTHON SOURCE LINES 101-103 **Question**: Following the same method as above, define a function which returns 33% of a number. Then use this function to find 33% of 300. .. GENERATED FROM PYTHON SOURCE LINES 103-118 .. code-block:: default def full_name(first_n): prefix = 'Mr. ' def family_name(fam_name): suffix = 'sahab' def kuniyat(z): return prefix + first_n + ' ' + fam_name + ' ' + z + ' ' + suffix return kuniyat return family_name .. GENERATED FROM PYTHON SOURCE LINES 119-122 .. code-block:: default full_name('Abdus')('Sattar')('Edhi') .. rst-class:: sphx-glr-script-out .. code-block:: none 'Mr. Abdus Sattar Edhi sahab' .. GENERATED FROM PYTHON SOURCE LINES 123-126 .. code-block:: default fam_name = full_name('Rashid') # fam_name is intermediate function .. GENERATED FROM PYTHON SOURCE LINES 127-130 .. code-block:: default Kuniyat = fam_name('Minhas') # kuniyat is innermost function .. GENERATED FROM PYTHON SOURCE LINES 131-134 .. code-block:: default Kuniyat('Shaheed') # Kuniyat is innermost function .. rst-class:: sphx-glr-script-out .. code-block:: none 'Mr. Rashid Minhas Shaheed sahab' .. GENERATED FROM PYTHON SOURCE LINES 135-144 Why use nested function * They can be used to avoid global variables. In upper example, the variable ``prefix``, can be set as global variable outside ``full_name``, but in this case we have made data encapsulation and now the variable `prefix` is only available inside the function where it is actually needed. This is also called information hiding. * To improve readability. If there is a tiny function that will only be invoked by the outer function, then this will help us determine what the function is all about. .. GENERATED FROM PYTHON SOURCE LINES 147-162 .. code-block:: default def print_name(name, gender): def add_prefix(s): if s == 'Male': return 'Mr.' else: return 'Mrs.' print(add_prefix(gender), name) print_name('lalak jan', 'Male') print_name('Fatima Jinnah', 'female') .. rst-class:: sphx-glr-script-out .. code-block:: none Mr. lalak jan Mrs. Fatima Jinnah .. GENERATED FROM PYTHON SOURCE LINES 163-166 We could have easily put ``add_prefix`` outside the function in outer scope, but in current case when we will read the code, it becomes clear to us that the function ``add_prefix`` is used only inside ``print_name`` .. GENERATED FROM PYTHON SOURCE LINES 168-180 .. code-block:: default def add_family_name(fam_name): def make_name(first): return first + fam_name return make_name name_maker = add_family_name(' Minhas') name_maker('Rashid') .. rst-class:: sphx-glr-script-out .. code-block:: none 'Rashid Minhas' .. GENERATED FROM PYTHON SOURCE LINES 181-183 ``nonlocal`` statement ----------------------- .. GENERATED FROM PYTHON SOURCE LINES 185-196 .. code-block:: default def square_after_adding_one(_in): x = _in def add_one(): x += 1 # trying to re-assign value of variable `x` from outer scope return x val = add_one() ** 2 print(val) .. GENERATED FROM PYTHON SOURCE LINES 197-201 .. code-block:: default # uncomment following line # square_after_adding_one(2) # -> UnboundLocalError local variable 'x' referenced before assignment .. GENERATED FROM PYTHON SOURCE LINES 202-222 .. code-block:: default x = 0 def square_after_adding_one(_in): x = _in def add_one(): nonlocal x x += 1 return x val = add_one() ** 2 print(val, 'squared after adding 1') print(x, 'global ') square_after_adding_one(2) print(x, 'global ') .. rst-class:: sphx-glr-script-out .. code-block:: none 0 global 9 squared after adding 1 0 global .. GENERATED FROM PYTHON SOURCE LINES 223-232 Above, the initial value of `x` is 0. Inside the function `square_after_adding_one`, we create a variable `x` with value 2. At this point this `x` is different from the global `x`. Then we call `add_one` which increments `x` by 1. Note that here we are using `nonlocal` keyword. This keyword is used to tell the function that the variable `x` is not local to the function `add_one` Therefore, we are using the variable `x` from the outer function `square_after_adding_one` whose value is 2. So, `x` is incremented by 1 and then squared. The output is 9. Once we are outside the function `square_after_adding_one`, the global `x` is still 0 because we have not touched the global `x` inside the function `square_after_adding_one`. .. GENERATED FROM PYTHON SOURCE LINES 232-253 .. code-block:: default x = 0 def square_after_adding_one(_in): x = _in def add_one(): global x x += 1 return x val = add_one() ** 2 print(val, 'squared after adding 1') print(x, 'in outer function') print(x, 'global ') square_after_adding_one(2) print(x, 'global ') .. rst-class:: sphx-glr-script-out .. code-block:: none 0 global 1 squared after adding 1 2 in outer function 1 global .. GENERATED FROM PYTHON SOURCE LINES 254-259 In above example, we are using `global` keyword instead of `nonlocal`. This means that we are using the global variable `x` inside the function `add_one`. Therefore, we are adding `1` to the global `x` whose value is `0`. So, `x` becomes `1` and then squared. Thus the value of ``val`` is `1`. There is another variable `x` which is inside the function `square_after_adding_one` whose value is `2`. This variable is not used inside the function `add_one`. .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 0.006 seconds) .. _sphx_glr_download_auto_examples_basics_nested_functions.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/AtrCheema/python-seekho/master?urlpath=lab/tree/notebooks/auto_examples/basics/nested_functions.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: nested_functions.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: nested_functions.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_