Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to create a nested function inside a function and when to call it from outside?

I have seen some code that has these structures.

Structure 1: An internal function is created within a function

def external_func(num):
    def internal_func(num2):
        return num2*2
    return internal_func(num + 10)


test = external_func(5)
print(test)

Structure 2: A function is calling another function that is outside itself.

def _internal_func2(num2):
    return num2 * 2

def external_func2(num):
    return _internal_func2(num + 10)

test2 = external_func2(5)
print(test2)

For this particular case, both functions provide the same output. Where and why should I use each one of these structures?

like image 879
Arman Mojaver Avatar asked Mar 12 '26 07:03

Arman Mojaver


1 Answers

One of the main benefits of Structure 1 is that it makes internal_func locally scoped to external_func. You are making it clear that internal_func should be accessed only by external_func. Treat it just like any other regular variable that was defined inside external_func. Similar to not having global variables scattered about, sometimes you want to "hide" an implementation inside other functions.

You can then have other similarly named internal_func's in other methods and their names won't clash:

In [39]: def external_func_x2(num):
    ...:     def f():
    ...:         return num * 2
    ...:     return f
    ...: 

In [40]: def external_func_x3(num):
    ...:     def f():
    ...:         return num * 3
    ...:     return f

One common purpose is to make functions that generate other functions based on certain conditions:

In [44]: def make_multiplier(mult):
    ...:     def f(num):
    ...:         return num*mult
    ...:     return f
    ...: 

In [45]: x4 = make_multiplier(4)

In [46]: x4(8)
Out[46]: 32

In [47]: x3 = make_multiplier(3)

In [48]: x3(8)
Out[48]: 24

You could do the same examples above with Structure 2 (or with functools.partial) but then it will be less readable, and you'll need to expose this inner f function in the outer scope/namespace, even though it's only used by the make_multiplier method. You'll also have to pass arguments around from one function to another, instead of having a closure like what we have with Structure 1.

If you are making this make_multiplier as part of some library/API, using Structure 1 "hides" this f function and makes it a bit clearer and more readable to clients/users of the library/API that they only need to "see" the make_multiplier method.

There is also an argument for maintainability. If you need to modify make_multiplier, it's already obvious that you need to modify f, and you can be pretty sure that modifying f will not break other parts of your code, since no one uses it other than make_multiplier.

Structure 2 is your standard good practice of "splitting your big functions into smaller more manageable and reusable functions". Its main advantages over Structure 1 are testability and reusability. It is much easier to test and mock out _internal_func2 directly, without needing to call external_func2, which is great if external_func2 is especially complicated in itself to call. It would also be very difficult to write tests that directly target a nested inner function.

It also makes _internal_func2 reusable by other methods. Comparing it to the example above for Structure 1, if you find yourself writing the same inner f nested inside many external_func's, then it's probably better to move that out and convert to Structure 2 style.

like image 127
Gino Mempin Avatar answered Mar 14 '26 20:03

Gino Mempin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!