是 pythonic:命名 lambdas

Posted

技术标签:

【中文标题】是 pythonic:命名 lambdas【英文标题】:Is it pythonic: naming lambdas 【发布时间】:2016-11-17 19:19:03 【问题描述】:

我开始欣赏 lambda 表达式在 python 中的价值,尤其是在函数式编程方面,map、functions returning functions 等。不过,我也一直在函数中命名 lambda,因为:

我需要多次使用相同的功能并且不想重复代码。 功能特定于它出现的功能;其他地方不需要。

当我遇到符合上述条件的情况时,我一直在编写一个命名的 lambda 表达式,以便对功能进行 DRY 并缩小范围。例如,我正在编写一个对一些numpy 数组进行操作的函数,并且我需要对传递给该函数的所有数组进行一些适度繁琐的索引(可以很容易地放在一行上)。我编写了一个命名的 lambda 表达式来进行索引,而不是编写一个完整的其他函数或在整个函数定义中多次复制/粘贴索引。

def fcn_operating_on_arrays(array0, array1):
    indexer = lambda a0, a1, idx: a0[idx] + a1[idx]
    
    # codecodecode
    
    indexed = indexer(array0, array1, indices)
    
    # codecodecode in which other arrays are created and require `indexer`
    
    return the_answer

这是对python lambdas 的滥用吗?我应该把它吸起来并定义一个单独的函数吗?

编辑

可能值得链接function inside function。

【问题讨论】:

【参考方案1】:

这不是 Pythonic 和 PEP8 discourages it:

始终使用 def 语句而不是赋值语句 将 lambda 表达式直接绑定到标识符。

是的:

def f(x): return 2*x

没有:

f = lambda x: 2*x

第一种形式表示生成的函数对象的名称是 特别是'f',而不是通用的'<lambda>'。这更 通常对回溯和字符串表示很有用。使用 赋值语句消除了 lambda 的唯一好处 表达式可以通过显式 def 语句提供(即它可以 嵌入到更大的表达式中)

对此的经验法则是考虑其definition:lambdas 表达式是匿名函数。如果你命名它,它就不再是匿名的了。 :)

【讨论】:

【参考方案2】:

我编写了一个命名的 lambda 表达式来进行索引,而不是编写一个完整的其他函数

好吧,您正在编写一个完全不同的函数。您只是用 lambda 表达式编写它。

为什么不使用def?您可以获得更好的堆栈跟踪和更多的语法灵活性,并且您不会丢失任何东西。这不像def 不能出现在另一个函数中:

def fcn_operating_on_arrays(array0, array1):
    def indexer(a0, a1, idx):
        return a0[idx] + a1[idx]
    ...

【讨论】:

def 在另一个函数中的 pythonic 程度如何?每当我看到有人这样做时,他们就是在滥用它。 @joshua.r.smith:将def 放在另一个函数中非常好。当他们想要关闭时,人们总是为装饰器或其他情况这样做。当内部函数不使用任何闭包变量时,我个人更喜欢避免使用它,因为能够访问该函数以进行测试或交互使用很方便。【参考方案3】:

这些在功能上(没有双关语)是相同的。

indexer = lambda a0, a1, idx: a0[idx] + a1[idx]

def indexer(a0, a1, idx):
    return a0[idx] + a1[idx]

如果您对其中一个有审美偏好,请使用它。

【讨论】:

以上是关于是 pythonic:命名 lambdas的主要内容,如果未能解决你的问题,请参考以下文章

解读Python的命名空间

python 命名空间

Python之命名空间闭包装饰器

python进阶之命名空间与作用域

python命名空间和作用域

Python命名空间和作用域