【问题标题】:When to create a nested function inside a function and when to call it from outside?何时在函数内部创建嵌套函数,何时从外部调用它?
【发布时间】:2021-05-19 03:35:43
【问题描述】:

我见过一些具有这些结构的代码。

结构1:在函数内部创建内部函数

def external_func(num):
    def internal_func(num2):
        return num2*2
    return internal_func(num + 10)


test = external_func(5)
print(test)

结构 2:一个函数正在调用其自身之外的另一个函数。

def _internal_func2(num2):
    return num2 * 2

def external_func2(num):
    return _internal_func2(num + 10)

test2 = external_func2(5)
print(test2)

对于这种特殊情况,两个函数提供相同的输出。我应该在哪里以及为什么要使用这些结构中的每一个?

【问题讨论】:

    标签: python function nested-function


    【解决方案1】:

    结构 1 的主要优点之一是它使 internal_func 本地范围为 external_func。换句话说,您明确表示internal_funcexternal_func 访问。就像在external_func 中定义的任何其他常规变量一样对待它。与没有散布全局变量类似,有时您希望将实现“隐藏”在其他函数中。

    然后您可以在其他方法中使用其他类似名称的internal_func,并且它们的名称不会冲突:

    In [39]: def external_func_x2(num):
        ...:     def f():
        ...:         return num * 2
        ...:     return internal_func
        ...: 
    
    In [40]: def external_func_x3(num):
        ...:     def f():
        ...:         return num * 3
        ...:     return internal_func
    

    一个共同的目的是使函数根据某些条件生成其他函数:

    In [44]: def make_multiplier(mult):
        ...:     def f(num):
        ...:         return num*mult
        ...:     return f
        ...: 
    
    In [45]: x4 = make_multiplier(4)
    
    In [46]: x4(8)
    Out[46]: 32
    
    In [47]: x3 = make_multiplier(3)
    
    In [48]: x3(8)
    Out[48]: 24
    

    您可以使用结构 2(或使用 functools.partial)执行上述相同的示例,但这样它的可读性会降低,并且您需要在外部范围/命名空间中公开这个内部 f 函数,即使它仅由 make_multiplier 方法使用。再一次,把它想象成在一个类中隐藏方法。您还必须将参数从一个函数传递到另一个函数,而不是像结构 1 那样使用闭包。

    如果您将此 make_multiplier 作为某些库/API 的一部分,使用结构 1“隐藏”此 f 函数并使其对库/API 的客户/用户更清晰、更易读只需要“看到”make_multiplier 方法。

    还有一个关于可维护性的论点。如果你需要修改make_multiplier,很明显你需要修改f,而且你可以很确定修改f不会破坏你代码的其他部分,因为除了@987654339之外没有人使用它@。

    结构 2 是“将大功能拆分为更小、更易于管理和可重用的功能”的标准良好实践。与结构 1 相比,它的主要优点是可测试性和可重用性。直接测试和模拟出_internal_func2 要容易得多,不需要调用external_func2,如果external_func2 本身调用起来特别复杂,那就太好了。编写直接针对嵌套内部函数的测试也非常困难

    它还使_internal_func2 可以被其他方法重用。将其与上述结构 1 的示例进行比较,如果您发现自己编写了相同的内部 f 嵌套在许多 external_func 中,那么最好将其移出并转换为结构 2 样式。

    【讨论】:

      猜你喜欢
      • 2018-05-27
      • 2012-11-20
      • 2017-12-02
      • 1970-01-01
      • 2018-06-12
      • 2019-12-16
      • 2019-12-29
      • 1970-01-01
      • 2014-10-01
      相关资源
      最近更新 更多