Normally you do it to make closures:
def make_adder(x):
def add(y):
return x + y
return add
plus5 = make_adder(5)
print(plus5(12)) # prints 17
Inner functions can access variables from the enclosing scope (in this case, the local variable x). If you're not accessing any variables from the enclosing scope, they're really just ordinary functions with a different scope.
Normally you do it to make closures:
def make_adder(x):
def add(y):
return x + y
return add
plus5 = make_adder(5)
print(plus5(12)) # prints 17
Inner functions can access variables from the enclosing scope (in this case, the local variable x). If you're not accessing any variables from the enclosing scope, they're really just ordinary functions with a different scope.
Aside from function generators, where internal function creation is almost the definition of a function generator, the reason I create nested functions is to improve readability. If I have a tiny function that will only be invoked by the outer function, then I inline the definition so you don't have to skip around to determine what that function is doing. I can always move the inner method outside of the encapsulating method if I find a need to reuse the function at a later date.
Toy example:
import sys
def Foo():
def e(s):
sys.stderr.write('ERROR: ')
sys.stderr.write(s)
sys.stderr.write('\n')
e('I regret to inform you')
e('that a shameful thing has happened.')
e('Thus, I must issue this desultory message')
e('across numerous lines.')
Foo()
Thoughts on nested / inner functions in Python for better encapsulation and clarity?
Is nesting function declarations bad practice?
Nested Function Best Practices (Python)
[Python] Should I use nested functions for this?
I think that’s mostly a style choice. Personally I would keep it outside; IMO it looks cleaner and more organized. Plus you may be coding down the line and realize “hey, I need that for something else” and if you nest it then you won’t be able to use it.
More on reddit.comBeen loving Python for 7+ years not and still going strong. I recently found myself writing more and more inner functions to encapsulate logic easier and make otherwise rather polluting/dead functions stick out less.
I like it, because it allows me to write way cleaner and less bloated code – clustering helper-functions to only where they need to be. Also decreases cognitive load considerably by not having to keep track on where a helper function is being used.
But it has gotten to a point where I'm genuinely concerned, because I have also started defining lambdas in inner-functions too! I know lambda shouldn't be used and PEP checker complains too, but it's so handy when combined with list comprehensions…
What are your thoughts on this?
Do you use nested functions yourself or do you consider it bad practice? Where else do you put helpers?
An example would be the following code:
def send_mail(
*,
subject: str,
body_plain: str,
send_to: Union[List[str], str, List[User], User],
send_cc: Optional[Union[List[str], str, List[User], User]] = None,
send_bcc: Optional[Union[List[str], str, List[User], User]] = None,
reply_to: Optional[Union[List[str], str, List[User], User]] = None
...
) -> None:
def _process_recipients(*, recipients: Optional[Union[List[str], str, List[User], User]]) -> List[str]:
""" Process various inputs for `send_to`, `send_cc` and `send_bcc` to a normalized
output that can be used by the emailing instance aka a list of emails """
_user_to_email = lambda x: x.email if isinstance(x, User) else x # transform user objects to mail
if not recipients: return [] # recipients are empty
if isinstance(recipients, str) or isinstance(recipients, User):
recipients = [recipients]
return [_user_to_email(recipient) for recipient in recipients]
...
send_to = _process_recipients(recipients=send_to)
send_cc = _process_recipients(recipients=send_cc)
send_bcc = _process_recipients(recipients=send_bcc)
...