0

I am trying to update a Python function's name incrementally based on the number of times it has been called.

An example of the original function can be seen below:

    def function(): 
       function.counter += 1
       return print('call 0')

function.counter = 0 

Below is the function I would like to be generated the second time the above function is called:

def function1(): 
    function.counter1 += 1
    return print ('call 1') 

And so on with each previous function call resulting in the creation of a new function which adds 1 to the previous function's name. Once function1() is called, function2() would be created, then once function 2() is called function3() would be created, and so on. Is there a straightforward way I could go about this?

user8891334
  • 171
  • 1
  • 4
  • 10
  • 6
    I'm sure someone can write code to do this, but why would you want to do something like this? If your loop runs a million times, you want to have declared 999,999 new functions? – dfundako Jun 13 '18 at 13:59
  • 7
    It's not impossible, but you're likely having a design/XY-problem here. Experienced Python programmers would not attempt to do what you are trying to do. (Unless there's a very specific context.) – timgeb Jun 13 '18 at 14:00
  • 1
    Why do you want to do this? Wouldn't it just be much easier to use a counter? – ltd9938 Jun 13 '18 at 14:00
  • `return print ('call 1')` is not doing what you think it is doing. Also your indentation is messed up – user3483203 Jun 13 '18 at 14:04
  • 1
    The syntax problems with your code examples make them impossible to interpret, and the general "what are you trying to do" is unclear. – Dave Jun 13 '18 at 14:06

2 Answers2

1

You should not declare multiple functions like that, there are better ways to accomplish what you want.

Generators

Using generators is well suited for your specific example.

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

g1 = count()
next(g1) # 0
next(g1) # 1

g10 = count(10)
next(g10) # 10

itertools module

The previous example is already implemented by itertools.count.

from itertools import count

g1 = count()
next(g1) # 0
next(g1) # 1

g10 = count(10)
next(g10) # 10

Closure

If you want a function with some state, use a closure instead of function attributes.

def count(start=0):
    _state = {'count': start - 1}

    def inner():
        _state['count'] += 1
        return _state['count']

    return inner

f1 = count()
f1() # 0
f1() # 1
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
0

This can be ideal approach to solve this problem,instead of creating multiple functions for each increment.Use a class and store the counter as variable and call the corresponding method to increment and get_count

class CouterExample(object):
    """Sample DocString:

    Attributes:
        counter: A integer tracking the current counter.
    """

    def __init__(self, counter=0):
        """Return a CounterExample object with counter."""
        self.counter = counter

    def increment(self, amount):
        """Sets the counter after increment."""
        if amount > 1:
            self.counter += amount

    def get_counter(self):
        """Return the counter value."""
        return self.counter
SaiKiran
  • 6,244
  • 11
  • 43
  • 76