Как сделать функцию-счетчик?

Нужна функция, которая при первом вызове возвращает 1, при втором 2, при третьем 3 и т.д. Затрудняюсь в этом вопросе


Ответы (4 шт):

Автор решения: Xander

Если функция должна запоминать внутри себя состояние, то лучше это делать не через функции, а через классы:

class IncrementCounter:
    
    def __init__(self):
        self._value = 0
    
    def new_value(self):
        self._value += 1
        return self._value


# Пример использования

counter1 = IncrementCounter()

print(counter1.new_value())  # Выведет 1
print(counter1.new_value())  # Выведет 2
print(counter1.new_value())  # Выведет 3


# Можно создать ещё один экземпляр счётчика,
# и он будет работать независимо от первого

counter2 = IncrementCounter()

print(counter2.new_value())  # Выведет 1
print(counter2.new_value())  # Выведет 2


# Если мы теперь вернёмся к первому счётчику,
# то увидим, что на него не повлиияло то,
# что мы делали со вторым
# Первый счётчик по прежнему помнит,
# что его последним значением было 3, и сейчас должно быть 4

print(counter1.new_value())  # Выведет 4

Впрочем, для вашего случая можно использовать и функцию-генератор. Но тогда обращаться к такому счётчику нужно будет не через вызов, а через протокол итерации:

def increment_counter():
    value = 0
    while True:
        value += 1
        yield value


# Пример использования

counter1 = increment_counter()

print(next(counter1))  # Выведет 1
print(next(counter1))  # Выведет 2
print(next(counter1))  # Выведет 3

Причём для простого инкрементного счётчика уже есть готовая функция в стандартной библиотеке, так что можно не писать её самостоятельно, а взять готовую:

from itertools import count


counter1 = count(1)

# Работает так же, как и в примере выше

print(next(counter1))  # Выведет 1
print(next(counter1))  # Выведет 2
print(next(counter1))  # Выведет 3
→ Ссылка
Автор решения: insolor

Без использования глобальных переменных (вместо этого используем замыкание):

def create_counter():
    i = 0
    
    def func():
        nonlocal i
        i += 1
        return i
    
    return func


counter = create_counter()
print(counter())  # 1
print(counter())  # 2
print(counter())  # 3

С помощью вызова create_counter() можно создать сколько угодно функций-счетчиков, каждая будет работать независимо от другой.

→ Ссылка
Автор решения: vadim vaduxa

как вариант, но так делать не стоит

def counter(__tmp=[0]):
    __tmp[0] += 1
    return __tmp[0]

print(counter())  # 1
print(counter())  # 2
print(counter())  # 3
→ Ссылка
Автор решения: eri

Класс:

class Func():
    def __init__(self):
        self.c = 0
    def __call__(self):
        self.c += 1
        return self.c

func = Func()
print(func(), func(),func())

Фабрика:

def Func():
    c = 0
    def _func():
        nonlocal c
        c += 1
        return c
    return _func

func = Func()
print(func(), func(),func())

Глобальная переменная:

c = 0
def func():
    global c
    c += 1
    return c

print(func(), func(),func())
→ Ссылка