Search code examples
pythonstatic-variables

Python static variables


I am trying to have a single static variable as an 'id' for all the child instantiations of this parent class. The problem I'm having is double counting of this ID, likely because the parent's __init__ gets called twice. But if I remove the explicit Parent().__init__() call, then the counter doesn't get incremented at all. How do I get the id to increment only ones? Here's my code snippet:

#!/usr/bin/python3
class Parent:
    cls_id = 0

    def __init__ (cls):
        cls.cls_inc_id()

    @classmethod
    def cls_inc_id (cls):
        cls.cls_id += 1

    @classmethod
    def child_inc_id (self):
        self.id += 1


class Child1 (Parent):

    def __init__ (self):
        Parent().__init__()
        self.id = super().cls_id
        print ("Child1 id: ", self.id)

class Child2 (Parent):

    def __init__ (self):
        Parent().__init__()
        self.id = super().cls_id
        print ("Child2 id: ", self.id)


child1 = Child1()
child2 = Child1()

child3 = Child2()
child4 = Child2()

My output is: %> ./static_vars.py

Child1 id:  2
Child1 id:  4
Child2 id:  6
Child2 id:  8

Thanks in advance


Solution

  • As others have mentioned, you're not using super constructor correctly, but also I would reference the actual class in the parent class, not the instance self which you incorrectly named cls:

    class Parent:
        cls_id = 0
    
        def __init__(self):
            self.id = Parent.cls_id
            Parent.cls_id += 1
    
    
    class Child1(Parent):
        def __init__(self):
            super().__init__()
            print ("Child1 id: ", self.id)
    
    
    class Child2(Parent):
        def __init__(self):
            super().__init__()
            print ("Child2 id: ", self.id)
    
    
    child1 = Child1()
    child2 = Child1()
    
    child3 = Child2()
    child4 = Child2()
    
    Child1 id:  0
    Child1 id:  1
    Child2 id:  2
    Child2 id:  3
    

    If you wanted a separate ID per type of class, you could use a dictionary mapping class to id:

    from collections import defaultdict
    
    
    class Parent:
        cls_ids = defaultdict(int)
    
        def __init__(self):
            self.id = Parent.cls_ids[type(self)]
            Parent.cls_ids[type(self)] += 1
    
    Child1 id:  0
    Child1 id:  1
    Child2 id:  0
    Child2 id:  1