1

I want to keep track via a counter, every time a class is instantiated. I was trying to do this by incrementing a counter defined as a class variable from inside the class' consructor ala:

class Cl:
   cntr = 0
   def __init__(self):
      cntr += 1

However, when I instantiate the class, I get an "UnboundLocalError: local variable 'cntr' referenced before assignement" I'm assuming this is because the constructor is treating it as a local variable. How do I reference the class variable from inside a method or constructor in Python 2.7?

GregH
  • 12,278
  • 23
  • 73
  • 109
  • Possible duplicate of [Difference between Class variables and Instance variables](https://stackoverflow.com/questions/19753897/difference-between-class-variables-and-instance-variables) – Nathan Vērzemnieks Jan 17 '18 at 20:58
  • 2
    @Stack that doesn't increment the class variable, it creates an instance variable shadowing the class variable. – wim Jan 17 '18 at 20:58
  • Yes, of course. `cntr` here is marked as local by the compiler because you assign to it, but even if you didn't, it would first check locals then globals and never check the class namespace. – juanpa.arrivillaga Jan 17 '18 at 20:59
  • Possible duplicate of [Python changing class variables](https://stackoverflow.com/questions/15790493/python-changing-class-variables) – Ilja Everilä Jan 17 '18 at 20:59
  • @NathanVērzemnieks true, my bad. Thanks – Stack Jan 17 '18 at 21:00
  • 3
    It's a bad design to do this in the class itself (it's not his responsibility to track instances). Do it in a metaclass, or some other external registry. – wim Jan 17 '18 at 21:00

2 Answers2

5

You just have to call the variable through the class:

class Cl:
    cntr = 0
    def __init__(self):
        Cl.cntr += 1  # <---Like this


print(Cl().cntr)  # prints 1
print(Cl().cntr)  # prints 2
print(Cl().cntr)  # prints 3
Eric Ed Lohmar
  • 1,832
  • 1
  • 17
  • 26
2
class Foo:
    n = 0
    def __init__(self):
        self._increment()

    @classmethod
    def _increment(cls):
        cls.n += 1

f1 = Foo()
f2 = Foo()

>>> f1.n
2

>>> f2.n
2
heemayl
  • 39,294
  • 7
  • 70
  • 76
Alexander
  • 105,104
  • 32
  • 201
  • 196