【问题标题】:Is it good to use inner function in a python function to make the logic clear?在python函数中使用内部函数使逻辑清晰吗?
【发布时间】:2018-06-12 07:14:16
【问题描述】:

下面是函数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 可以直接使用 -- good
  2. 我们可以很容易地知道some_logic是和foo相关的,实际上只用在foo函数中——good
  3. 每次调用函数 foo 时,都会创建一个新的内部函数 -- 不太好

外层函数版本

  1. val_in_foo_scope 不能直接使用 -- 不太好
  2. 我们无法直接看到 some_logicfoo 之间的相关性 -- 不太好
  3. some_logic 将被创建一次 -- good
  4. 全局命名空间中会有这么多函数 -- 不太好

那么,哪个解决方案更好还是有其他解决方案?

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

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

【问题讨论】:

  • 如果逻辑完全依赖并被主函数使用,那么内部函数应该做,否则如果逻辑被多个方法使用并且是独立的,两种不同的方法会清楚
  • 如果您确定您的内部函数只适合在该函数内部使用,并且不需要在外部执行,那么在内部定义它是非常有意义的。
  • 如果它是一个简单的函数,则使用 lambda,如果它是复杂的并且你不想让它“公开”,则使用一个内部函数。如果您想将其设为“公共”并使用实例的成员,请使用方法。如果使用类成员,则使用类方法。最后使用一个全局函数,如果它足够通用,可以被其他类/函数使用。
  • @Mixone 好吧,我将其添加为答案并使用私有方法对其进行了扩展。
  • @Mixone 好像和外层函数版本一样,使用类和内层函数版本相比,不能清楚地显示相关性?

标签: python refactoring


【解决方案1】:

您在优缺点列表中忘记了一点:可测试性。将some_logic 排除在foo 之外使其可单独测试,如果它确实是一个“复杂”(因此很可能很关键)功能,这一点很重要。

作为一般规则,只有在满足这两个条件时才使用内部函数:这是微不足道的东西传递所需的上下文(“外部”函数的上下文)会很痛苦。

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

【讨论】:

    【解决方案2】:

    如果是简单函数,请使用lambda

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-25
      • 2016-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      相关资源
      最近更新 更多