自动增量可赎回?

时间:2012-01-11 18:08:06

标签: python auto-increment counter

我有一个方法,我需要将一个不断增加的整数传递给另一个函数。

我可以这样做:

def foo(i):
    print i

def bar():

    class Incrementer(object):
        def __init__(self, start=0):
            self.i = start

        def __get__(self):
            j = self.i
            self.i += 1
            return j

    number = Incrementer()
    foo(number)
    foo(number)
    foo(number)

正确输出0 1 2 ...,但我觉得我忽略了一种更简单(或内置)的方式吗?

2 个答案:

答案 0 :(得分:14)

尝试itertools.count() - 它完全符合您的需求:

>>> c = itertools.count()
>>> next(c)
0
>>> next(c)
1
>>> next(c)
2

答案 1 :(得分:7)

通常,如果您需要在对函数的一次调用和下一次调用之间保持状态,那么您想要的是对象(您的解决方案)还是生成器。在某些情况下,一个会比另一个更简单,但原则上没有任何错误与你如何完成它(虽然你似乎在实现上有一些问题)。

斯文的建议itertools.count()是一个发电机。它的实现是这样的:

def count():
    i = 0
    while True:
        yield i
        i += 1

现在,如果您希望它像函数一样可调用,而不是必须执行next(c),那么您可以定义一个包装器来实现它:

 def count(c=itertools.count()):
     return next(c)

或者不可避免的单行lambda:

count = lambda c=itertools.count(): next(c)

然后count()每次调用它时都会返回下一个整数。

当然,如果您希望能够创建任意数量的可调用函数,每个函数都有自己的计数器,您可以为此编写工厂:

def counter():
    return lambda c=itertools.count(): next(c)

然后是:

c = counter()
print c()   # 0
print c()   # 1
# etc

这对我来说似乎比一个对象更简单,但不是很多。如果你的状态或逻辑更复杂,那么对象的封装可能会胜出。