自增可调用函数?

11 投票
2 回答
5299 浏览
提问于 2025-04-17 10:02

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

我可以这样做:

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 个回答

8

一般来说,如果你需要在一次函数调用和下一次调用之间保持状态,你可以选择使用一个对象(就是你现在的解决方案)或者一个生成器。在某些情况下,使用其中一个会比另一个更简单,但你现在的做法原则上没有什么问题(虽然你在实现上似乎遇到了一些麻烦)。

Sven 提出的建议,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

在我看来,这种方式仍然比使用对象简单一些,但差别不大。如果你的状态或逻辑再复杂一点,使用对象的封装性可能会更有优势。

21

试试 itertools.count() -- 它正好满足你的需求:

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

撰写回答