我刚刚遇到以下代码,它运行正常,但它似乎很奇怪,因为它甚至不是一个闭包,我想知道它是否是在性能或最佳实践方面编码的正确方法,或者应该所有这些都被一个带有所有逻辑的常规for循环所取代?
mylist = [
{'one': 20,
'two': 4},
{'one': -6,
'two': 64},
{'one': 18,
'two': 1},
{'one': 16,
'two': 100},
# ...
]
def business_function(a_list):
def compute_function(row):
"""
suppose some more complex computations + appending extra values
than this dummy example
"""
row['total'] = row['one'] + row['two']
return row
def filter_function(item):
"""
suppose some complex logic here
"""
return item['one'] > 5
# suppose there is some code here ...
filtered_list = [compute_function(item) for item in a_list if filter_function(item)]
# and some more code here ...
return filtered_list
print business_function(mylist)
答案 0 :(得分:3)
我发现使用像这样的本地范围的函数没有任何问题。
除非外部函数将被称为很多,否则对性能的影响将是最小的;例如,在调用外部函数时,已经编译了这两个函数的代码。发生 extra 的所有事情是加载代码对象常量,附加到函数并且该函数存储在局部变量中。
通过将它们保持在本地范围内,您可以清楚地了解它们的实用程序仅适用于business_function
范围。
答案 1 :(得分:2)
我会说不,只是因为有更好的方法来做这个方法所希望的。
否则只需使它们正常运行。
答案 2 :(得分:2)
这有一个小的缺点,因为每次调用封闭函数时都会创建内部函数对象,这是一个很小的性能损失。然而,这很少是一个问题,并且改进的代码封装可能使它值得。
另一种方法是创建一个类,但这不会减少开销。
答案 3 :(得分:2)
我不喜欢这种嵌套定义的使用。作者可能这样做是为了提高可读性或阻止其他人使用他的私人功能。
如果作者想要将这些函数“标记”为私有,则应该使用下划线为其名称添加前缀。通过这种方式,他也可以在代码的其他部分重用这些函数,而无需复制它们。
如果他这样做是为了提高可读性......那么,为什么不把它们放在那个功能之外呢? 如果他们做了一些真正的计算和过滤,那么他们就应该拥有自己的文档和评论的“顶级”功能。
可能只应在装饰器或其他真正罕见的情况下使用闭包。
答案 4 :(得分:0)
如果函数不使用外部函数的局部变量,并且它们不是简单的单行,那么我将它们放在全局范围内。
否则,您的代码的读者将被强制读取所有函数定义(如果它们是闭包并使用/更改外部局部变量)以了解外部函数的作用。
如果它们在外部定义,那么名称和相应的文档字符串可能足以理解它们在外部函数中的角色。