5

Below is the basic logic for function foo:

def foo(item_lst):
    val_in_foo_scope = 1        

    for item in item_lst:
        # some logic to deal with item
        # val_in_foo_scope used
        pass

    return 0

The logic in the loop can be very complex, in order to make the code more clear, I want to split the logic with a separate function.


With inner function:

def foo(item_lst):
    val_in_foo_scope = 1 

    def some_logic(item):
        # val_in_foo_scope used
        pass

    for item in item_lst:
        some_logic(item)

    return 0

With outer function:

def some_logic(item, val):
    # val used
    pass

def foo(item_lst):
    val_in_foo_scope = 1 

    for item in item_lst:
        some_logic(item, val_in_foo_scope)

    return 0

The inner function version

  1. val_in_foo_scope can be used directly -- good
  2. we can easily know that the some_logic is relevant with foo, actually only be used in function foo -- good
  3. each time function foo is called, a new inner function will be created -- not so good

The outer function version

  1. val_in_foo_scope can not be used directly -- not so good
  2. we can not see the relevance between some_logic and foo directly -- not so good
  3. some_logic will be created one time -- good
  4. there will be so many functions in the global namespace -- not so good

So, which solution is better or is there any other solutions?

Factors below or any other factors you come up with can be considered:

  1. val_in_foo_scope is used or not
  2. whether the time cost to create inner function each time can be ignored
9
  • 2
    if the logic is completely dependent and used by the main function then an inner function should do, otherwise if the logic is used by multiple methods and is independent, two different methods would make things clear Commented Jan 2, 2018 at 15:17
  • 1
    If you are sure that your inner function is suited only for the use within that function, and won't be needed to execute outside it, then it makes perfect sense to define it inside. Commented Jan 2, 2018 at 15:18
  • 1
    Use lambda if it's a simple function, use an inner function if it is complex and you don't want to make it "public". Use a method if you want to make it "public" and uses members of the instance. Use a class method if it uses class members. And lastly use a global function if it's general enough to be used by other classes/functions. Commented Jan 2, 2018 at 15:22
  • 1
    @Mixone alright, I added it as answer and expanded it with private methods. Commented Jan 2, 2018 at 15:34
  • 1
    @Mixone It seems that like the outer function version, using class can not show the relevance clearly compared with the inner function version? Commented Jan 2, 2018 at 15:35

2 Answers 2

3

Use lambda if it's a simple function.

Use an inner function if it is complex and you don't want to make it "public".

Use a "private" method if you want to mark it hidden and uses members of the instance.

Use a method if you want to make it "public" and uses members of the instance.

Use a class method if it uses class members.

And lastly use a global function if it's general enough to be used by other classes/functions.

Sign up to request clarification or add additional context in comments.

Comments

3

You forgot one point in your pro/cons list: testability. Keeping some_logic out of foo makes it testable in isolation, which is important if it's indeed a "complex" (hence very probably critical) function.

As a general rule, only use inner functions when you have both of those conditions: it's trivial stuff and passing the required context (the 'outer' function's context) would be a pain.

(nb: I'm of course not talking about using inner functions for closures - like in a decorator - here).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.