Function Inside a Function

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

One of the main benefits of Structure 1 is that it makes internal_func locally scoped to external_func. In other words, 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 internal_func
...:

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

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. Again, think of it like hiding methods inside a class. 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 major 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.

call a nested function (function inside another function)

THIS IS NOT SOMETHING YOU SHOULD DO, but you could create a nested function attribute like so:

def foo():
# for closures or strictly local function
# then this is useful!
# ugly hack other wise to try and create methods.
def bar():
print('bar')

# if there are multiple function, return a container...
return bar

Then:

foo.bar=foo()
foo.bar()
# prints 'bar'

BUT, this is far easier with a class:

class Foo:
# class can hold related methods, setters and getters,
# protected variables, etc.
# Python is DESIGNED to do this.
def bar(self):
print('bar')

Then:

f=Foo()
f.bar()
# prints 'bar'

Why is it easier?

  1. Because Python is designed to use the second example, a class, but the first example is a hack. The ways to use classes are well documented and tested.
  2. It does not scale well. Each function attribute needs to be added from the OUTSIDE of the function.
  3. You will run into local vs global namespace issues if you try and change variables. Classes gracefully support both instance and class data.

It is horrible -- don't do it. Use a class or a module to hold methods.


After a morning coffee, you can potentially do something like this if you really want to add function attributes -- Use a decorator to monkey patch a function:

def add_func_to(function):
# decorator to add function attributes
def attr_f(new_func):
setattr(function, new_func.__name__, new_func)
return new_func
return attr_f

# some function to add an attribute function to:
def foo():
pass

@add_func_to(foo)
# added attribute function below
def attr_f(string):
print(string)

Test it:

>>> foo.attr_f('test')
test

This is still limited vs a class or module since you will be limited to using global or passed variables. It is more applicable if you just want to add a function attribute to an existing function and be done with it...

python: is it legal to pass self to the nested function inside the class method?

Any function defined within a scope can use variables from its enclosing scope. In this case, you're defining a function within a function, so all the variables in the enclosing function are available - self, param1, and param2. So you can pass self as a parameter to the inner function, but since it already has access to self, there's not much point to doing so.

If you create new variables with these names inside your new function, they "shadow" the variables with those names in the outer scope, meaning the names from the outer scope are inaccessible as long as the same names refer to something else in the inner scope. self is just a normal variable name with no special meaning, except that it's the first parameter of a class's instance function, and thus gets passed implicitly when the method is called via the dot operator - meaning that it's subject to these rules.

In your inner function, you're passing self explicitly, which is harmless but also pointless in this case. Python 3.6 (and Pycharm) is giving you warnings because it can't do typechecking on this, but that's all.

In other words, this would work just as well and cause no errors:

def func1(self, param1, param2):
def inner_func1():
print(self, self.a, self.b)

inner_func1()

Functions inside a function in Julia

Since google led me here, perhaps I add a comment:

Nested functions used to be slower, see for instance this discussion on github... in 2013. But not any more: running exactly the tests there on v0.6, they are all the same speed now.

This is still true for me if (like the question) the inner function implicitly depends on things defined within the outer function, which would have to be passed explicitly if it were a free-standing function.

Calling function inside function is not defined

Your code has an object users which when initialized, runs a function which in turn returns an object with methods as its properties.

The users object is globally available, i.e, you can use users.something anywhere as long as its initialized.

the functions that return from the user object have scopes limited to the return function where they're defined. They can only be accessible outside the scope using user.functionName in your case user.init() or user.validation() etc.,

but once you go a level inside the code to where the functions are defined, you are entering into the scope of the function which was used to create the user object. At this level, you do not have access to other functions as earlier, but only the methods or variables which are defined within the scope of the function you are in.

For example: I've added a function consoleStatement() below. and it will print out some console logs, if you run the code, you will observe that the console log for year will output different year the second time when you defined the year as 2019.

var users = (function($) {
"use strict";

return {
init: function() {
this.validation();
},
validation: function() {
$('#form input').on('blur', function(){

// This will NOT work because there is no ajaxcheck defined here
ajaxcheck();

// This will work because the "this" keyword uses the object (this)
this.ajaxcheck();

// This will definitely work because the function is available globally
checkMyAjax();
});
},
ajaxcheck: function() {
console.log('ajax call');
},
consoleStatement: function() {
var name = "Marco";
var year = 2020;
console.log('Name is: '+name);
console.log('Year is: '+year);
},
}
})( jQuery );

function checkMyAjax () {
console.log('ajax call again');
}

jQuery(document).ready(function() {
var year = 2019;
users.init();
console.log('Year is: '+year);
users.consoleStatement();
});

Scope of a function lies with in the block it is defined, for example function myFunction () {} so in order to access variables and functions, they either must be in the scope of the function or must be available globally. I.e, outside all functions.

Here is a gist I've created with line numbers for you to understand clearly: https://gist.github.com/ypk/303659beb2e74429858903052e0c2557



Related Topics



Leave a reply



Submit