用闭包替换简单的Python类是否有益?

用闭包替换简单的Python类是否有益?,python,closures,Python,Closures,我有以下Python类: class class A: """a class that increments internal variable""" def __init__(self, x): self._x = x def incr(self): self._x = (self._x + 1) % 10 return self._x 我听过一次演讲,建议只使用构造函数和另一个方法的类真的应该被函数取代 下面是我的尝试

我有以下Python类:

class class A:
    """a class that increments internal variable"""
    def __init__(self, x):
        self._x = x
    def incr(self):
        self._x = (self._x + 1) % 10
        return self._x
我听过一次演讲,建议只使用构造函数和另一个方法的类真的应该被函数取代

下面是我的尝试(针对Python 2.7):

运行它:

def test1():
    """testing closure vs. class"""
    print 'class...'
    a = A(10)
    print a.incr()
    print a.incr()

    print 'closure...'
    incr = incrX(10)
    print incr()
    print incr()

$ python closure.py 
running closure experiments
class...
1
2
closure...
1
2
所以我的问题是:


用闭包替换像a这样的类是否有好处?只是想更好地理解闭包。

闭包和高阶函数的真正好处在于,它们可以代表程序员有时的想法。如果作为程序员,你发现你脑子里想的是一段代码,一个函数,一条关于如何计算(或做某事)的指令,那么你应该为此使用闭包

另一方面,如果你心目中的更像是一个对象,一个东西(碰巧有一些属性、方法、指令、功能等等),那么你应该将它编程为一个对象,一个类

在你的情况下,我认为实现这一点的最佳方法是两者都不是;-)我会用发电机来做这件事:

def incrX(i):
  while True:
    i += 1
    i %= 10
    yield i

incr = incrX(10)
print incr.next()
print incr.next()

使用闭包,可以保存
self
变量。特别是,当有许多变量要传递时,闭包的可读性会更高

class Incr:
    """a class that increments internal variable"""
    def __init__(self, i):
        self._i = i
    def __call__(self):
        self._i = (self._i + 1) % 10
        return self._i

谢谢@Alfe,这个课程是我的一个生成视点的相机类的简化——我不确定我是否能应用生成器的思想。我想没有明确的理由总是用这两种类型的方法替换一个类和一个函数。@M-V:Laotseu说:“闭包是穷人的对象,对象是穷人的闭包”;)更严重的是:虽然Pytho对函数式编程有一些不错的支持,但它首先还是一种OO语言,闭包是作为对象实现的。这是一个很好的特性,当这是您真正需要的时候(大多数装饰函数等),但是类作为闭包没有什么错-事实上,您甚至可以实现magic
\uuuu call\uuuu
方法,以便在闭包有意义时(在您深入的示例中就是这样)@M-V:你当然可以用这个发电机来制作你的相机。但我认为这可能是错误的。最有可能的是,您的相机要传送的下一个数字应该存储在该对象的字段中,就像您在问题中实现的一样。@Brunodesshuilliers-谢谢。是的,那个老祖,那个超级能说会道的人
class Incr:
    """a class that increments internal variable"""
    def __init__(self, i):
        self._i = i
    def __call__(self):
        self._i = (self._i + 1) % 10
        return self._i
def incr(i): 
    """closure that increments internal variable"""
    def incr():
        nonlocal i
        i = (i + 1) % 10
        return i
    return incr
print('class...')
a = Incr(10)
print(a())   # 1
print(a())   # 2

print('closure...')
b = incr(10)
print(b())   # 1
print(b())   # 2