在python函数中使用内部函数以使逻辑清晰是否合适?

时间:2018-01-02 15:14:50

标签: python refactoring

以下是函数 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

循环中的逻辑可能非常复杂,为了使代码更清晰,我想用单独的函数拆分逻辑。

内部功能:

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

使用外部功能:

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

内部功能版

  1. val_in_foo_scope 可以直接使用 -
  2. 我们很容易知道 some_logic foo 相关,实际上只能在函数 foo 中使用 - good < /强>
  3. 每次调用函数 foo 时,都会创建一个新的内部函数 - 不太好
  4. 外部功能版

    1. val_in_foo_scope 不能直接使用 - 不太好
    2. 我们无法直接看到 some_logic foo 之间的相关性 - 不太好
    3. some_logic 将被创建一次 - good
    4. 全局命名空间中会有这么多功能 - 不太好
    5. 那么,哪种解决方案更好,还是有其他解决方案?

      可以考虑以下因素或您提出的任何其他因素:

      1. 是否使用val_in_foo_scope
      2. 每次创建内部函数的时间成本是否可以忽略

2 个答案:

答案 0 :(得分:3)

如果它是一个简单的函数,请使用lambda

如果内部函数很复杂并且您不想使其成为“公共”函数,请使用它。

如果您想将其标记为隐藏并使用该实例的成员,请使用“private”方法。

如果要将其设为“公共”并使用实例的成员,请使用方法。

如果使用类成员,请使用类方法。

最后使用全局函数,如果它足够通用,可以被其他类/函数使用。

答案 1 :(得分:1)

您忘记了优点/缺点列表中的一点:可测试性。将some_logic保留在foo之外会使其在孤立状态下可测试,如果它确实是一个“复杂”(因此很可能是关键的)功能,这一点非常重要。

作为一般规则,只有当你同时拥有这两个条件时才使用内部函数:传递所需上下文(“外部”函数的上下文)的琐碎的东西会很痛苦。

(nb:我当然不是在谈论使用内部函数进行闭包 - 就像装饰器一样 - 在这里)。