views:

739

answers:

5

What benefit or implications could we get with Python code like this:

class some_class(parent_class):
    def doOp(self, x, y):
        def add(x, y):
            return x + y
        return add(x, y)

I found this in an open-source project, doing something useful inside the nested function, but doing absolutely nothing outside it except calling it. (The actual code can be found here.) Why might someone code it like this? Is there some benefit or side effect for writing the code inside the nested function rather than in the outer, normal function?

+2  A: 

I can't image any good reason for code like that.

Maybe there was a reason for the inner function in older revisions, like other Ops.

For example, this makes slightly more sense:

class some_class(parent_class):
    def doOp(self, op, x, y):
        def add(x, y):
            return x + y
        def sub(x,y):
            return x - y
        return locals()[op](x,y)

some_class().doOp('add', 1,2)

but then the inner function should be ("private") class methods instead:

class some_class(object):
    def _add(self, x, y):
        return x + y
    def doOp(self, x, y):
        return self._add(x,y)
THC4k
Yeah, maybe doOp took a string to specify which operator to use on the arguments...
Skilldrick
you shouldn't use classes in python simply for organizing functions...
Wahnfrieden
A: 

The idea behind local methods is similar to local variables: don't pollute the larger name space. Obviously the benefits are limited since most languages don't also provide such functionality directly.

avguchenko
+1  A: 

Are you sure the code was exactly like this? The normal reason for doing something like this is for creating a partial - a function with baked-in parameters. Calling the outer function returns a callable that needs no parameters, and so therefore can be stored and used somewhere it is impossible to pass parameters. However, the code you've posted won't do that - it calls the function immediately and returns the result, rather than the callable. It might be useful to post the actual code you saw.

Daniel Roseman
I've added a link to the original code in a comment on my question. As you can see, mine is a simplified example, but it's still almost the same.
Hosam Aly
+1  A: 

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.

Ross Rogers
+9  A: 

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.

Adam Rosenfield
For that I'd prefer partials: `plus5 = functools.partial(operator.add, 5)`. Decorators would be a better example for closures.
THC4k
Thanks, but as you can see in the snippet I posted, that's not the case here: the nested function is simply being called in the outer function.
Hosam Aly