Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple function that returns a number incremented by 1 on each call, without globals?

I am trying to write a python function that on the first call, returns a 1. On the second call, returns a 2. On the third, a 3. Etc.

Currently, I have achieved this using a global variable:

index = 0

def foo():
    global index
    index += 1
    return index

When calling the function three times:

print(foo())
print(foo())
print(foo())

It returns the values expected:

1
2
3

But, I've read that it is bad practice to use global variables. So, I was wondering if the same result could be achieved without using globals.

Any suggestion?

Thank you for your help.

like image 475
manocormen Avatar asked Jul 19 '16 10:07

manocormen


People also ask

How do you increment a variable in a function?

The increment operator ( ++ ) increments its operand by 1 ; that is, it adds 1 to the existing value. There's a corresponding decrement operator ( -- ) that decrements a variable's value by 1 .

How do you increment a value in Python?

Python increment operator In python, if you want to increment a variable we can use “+=” or we can simply reassign it “x=x+1” to increment a variable value by 1.


2 Answers

Using a closure:

def make_inc():
    val = [0]
    def inc():
        val[0] += 1
        return val[0]
    return inc

inc = make_inc()
print inc()
print inc()
print inc()

Using a class (the most obvious solution in an OOPL ):

class Inc(object):
    def __init__(self):
        self._val = 0

    def __call__(self):
        self._val += 1
        return self._val


inc = Inc()
print inc()
print inc()
print inc()

Using a generator (not directly callable, you'll have to use the .next() method):

def incgen():
    val = 0
    while True:
        val += 1
        yield val


inc = incgen()
print inc.next()
print inc.next()
print inc.next()
like image 93
bruno desthuilliers Avatar answered Oct 19 '22 20:10

bruno desthuilliers


You can use function attributes:

def f():
    f.counter = getattr(f, 'counter', 0) + 1
    return f.counter

Or closures:

def w():
    counter = 0
    def f():
        nonlocal counter
        counter += 1
        return counter
    return f
like image 7
Sergey Gornostaev Avatar answered Oct 19 '22 18:10

Sergey Gornostaev