在许多情况下,有两种实现选择:闭包和可调用类。例如
class F:
def __init__(self, op):
self.op = op
def __call__(self, arg1, arg2):
if (self.op == 'mult'):
return arg1 * arg2
if (self.op == 'add'):
return arg1 + arg2
raise InvalidOp(op)
f = F('add')
或者
^{pr2}$在做出选择时,应该考虑哪些因素,无论是哪一个方面?在
我能想到两个:
似乎一个闭包总是有更好的性能(不能 想想反例)。
我认为在某些情况下,关闭不能完成任务(例如,如果 它的状态会随着时间而变化)。
我穿对了吗?还有什么可以补充的?在
请注意,由于之前在我的测试代码中发现了一个错误,我原来的答案是不正确的。修订版如下。
我做了一个小程序来测量运行时间和内存消耗。我创建了以下可调用类和一个闭包:
我定时调用接受不同数量参数的简单函数(
math.sqrt()
有1个参数,math.pow()
有2个参数,max()
有12个参数)。在我在Linux x64上使用了CPython 2.7.10和3.4.3+。我只能在python2上进行内存评测。我使用的源代码是可用的here。在
我的结论是:
math.pow()
的调用大致相同,而通过可调用类的运行时开销大约是这个值的两倍。在这些都是非常粗略的估计,它们可能会因硬件、操作系统和所比较的功能而有所不同。但是,它可以让您了解使用各种可调用的影响。在
因此,这支持了(与我之前写的相反),由@RaymondHettinger给出的接受答案是正确的,并且闭包应该优先用于间接调用,至少只要它不妨碍可读性。另外,感谢@AXO指出了我原始代码中的错误。在
关闭速度更快。类更灵活(也就是说,有更多的方法可用,而不仅仅是调用。在
我知道这是一篇旧文章,但是我没有看到列出的一个因素是,在Python(pre-nonlocal)中,不能修改引用环境中包含的局部变量。(在您的示例中,这样的修改并不重要,但从技术上讲,无法修改这样的变量意味着它不是一个真正的闭包。)
例如,以下代码不起作用:
上面对c的调用将引发UnboundLocalError异常。在
通过使用可变表(如字典)可以轻松解决这一问题:
^{pr2}$当然,这只是一个变通办法。在
相关问题 更多 >
编程相关推荐