您的位置:首页 > 编程语言 > Python开发

nested function in python

2016-06-04 20:59 615 查看


Nested
Function in Python

up
vote42down
votefavorite
11

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?

python nested-function
shareimprove
this question
edited Jan
17 '11 at 9:41

asked Oct 19 '09 at 14:40





Hosam Aly
19.7k28109158

 
2 
Is this the actual code you found, or just a simplified example you constructed? – MAK Oct
19 '09 at 17:43
 
It's a simplified example. The actual code can be found here: bazaar.launchpad.net/%7Eopenerp/openobject-server/trunk/… – Hosam
Aly Oct
20 '09 at 8:03
1 
Your link (which points to HEAD) is now not accurate. Try: bazaar.launchpad.net/~openerp/openobject-server/trunk/annotate/… – Craig
McQueen Dec
3 '09 at 1:21
 
You're right Craig. Thank you. – Hosam
Aly Dec
7 '09 at 11:32
add
a comment


6 Answers

activeoldestvotes

up vote64down
voteaccepted
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.

shareimprove
this answer
answered Oct 19 '09 at 16:05





Adam Rosenfield
232k62355476

 
2 
For that I'd prefer partials: 
plus5
= functools.partial(operator.add, 5)
. Decorators would be a better example for closures. – Jochen
Ritzel Oct
19 '09 at 18:09
2 
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 Oct
20 '09 at 8:05
add
a comment





up vote31down
vote
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()


shareimprove
this answer
edited May
12 '14 at 18:36

answered Oct 19 '09 at 15:03





Ross Rogers
8,4891356108

 
 
I agree with this completely. – Tommy Apr
21 '14 at 19:44
add
a comment
up vote13down
vote
One potential benefit of using inner methods is that it allows you to use outer method local variables without passing them as arguments.
def helper(feature, resultBuffer):
resultBuffer.print(feature)
resultBuffer.printLine()
resultBuffer.flush()

def save(item, resultBuffer):

helper(item.description, resultBuffer)
helper(item.size, resultBuffer)
helper(item.type, resultBuffer)


can be written as follows, which arguably reads better
def save(item, resultBuffer):

def helper(feature):
resultBuffer.print(feature)
resultBuffer.printLine()
resultBuffer.flush()

helper(item.description)
helper(item.size)
helper(item.type)


shareimprove
this answer
edited Dec
21 '12 at 11:11

answered Nov 15 '12 at 12:32





Kuba
1,0041121

 add
a comment
up vote7down
vote
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)


shareimprove
this answer
edited Oct
19 '09 at 15:55

answered Oct 19 '09 at 14:55





Jochen Ritzel
55.5k8106145

 
 
Yeah, maybe doOp took a string to specify which operator to use on the arguments... – Skilldrick Oct
19 '09 at 15:03
2 
you shouldn't use classes in python simply for organizing functions... – aehlke Feb
22 '10 at 22:45
 
@aehlke - why not? – ArtOfWarfare Oct
9 '13 at 15:27
1 
@ArtOfWarfare it's preferred to simply use modules. Classes are for state. – aehlke Oct
9 '13 at 15:59
add
a comment
up vote4down
vote
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.

shareimprove
this answer
answered Oct 19 '09 at 14:57





avguchenko
1,79011118

 add
a comment
up vote1down
vote
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.

shareimprove
this answer
answered Oct 19 '09 at 14:59





Daniel Roseman
301k23376459

 
1 
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 Oct
20 '09 at 8:06


When
to use python function nesting?



up
vote2down
votefavorite

I am writing a program that creates backup of directories.

Which of the following approach is better for code organization?

Create separate class for Backup and Zip logic -
class BackupUtil:
def backup(self):
None

class ZipUtil:
def archive_dir(self):
None


Or use function nesting like this -
class BackupUtil:
def backup(self):
def archive_dir():
None
None


python code-quality code-organization
shareimprove
this question
asked Mar 18 '14 at 8:37





Kshitiz Sharma
3072411

 add
a comment


3 Answers

activeoldestvotes

up vote5down
vote
In general, when the inner function is small and you want to make it clear that it's only useful to the enclosing function. Alternatively, when you need to return a function. The latter scenario is trivial since generally the inner function relies on variables
in the enclosing functions's scope, so declaring it anywhere else isn't an option. You might be able to use a lambda in that case, but anything longer than one expression would need a full function declaration.

Without the implementations it's hard to say which one you should choose in this case. I would hasten to add that you don't have to put everything in a class either.

shareimprove
this answer
answered Mar 18 '14 at 11:42





Doval
12.8k22946

 add
a comment


up vote0down
vote
Keeping the two separate would be useful for quite a few reasons:

1) You will have more flexibility working with either class (especially Class inheritance)

2) You can transform the two classes into modules that you can use in your other codes independently from each other

3) You will avoid unnecessarily creating a larger class when you maybe only need to use one of the two features

4) Keeping the functions separate also increases code readability when you later call these functions

Hope that helps clarify somethings.

shareimprove
this answer
answered Mar 18 '14 at 11:07





sshashank124
1012

 add
a comment
up vote0down
vote
TL;DR: Use function nesting when you need the characteristics of function nesting

Function Nesting Use Cases (mostly functional idioms, almost certainly incomplete since it's off the top of my head):
closures
function factory (programmatic function creation based on parameters)
creating functions by calling functool.partial
creating functions by using lambda
any other reasons you need to create functions during call time

Trade-offs:
functions are strongly coupled
the code is always called (unless it's in an if block)
additional code complexity
additional runtime cost (potentially, because the inner function get's re-defined with every call to the outer function)
much harder to extend
much harder to introspect on the inner function defintion

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: