pythoninner-classesstatic-variables

Python static class variable in nested class


I have a nested class that uses static vars to have class wide parameters and accumulators.

If I do it as a standalone class it works.

If I do a nested class and inherit the standalone class, it works.

But I can't get a nested class to have static class variables, the interpreter gets confused. What am I doing wrong?

Code snippet:

class Cl_static_parameter_standalone:
    #static var common to all instances. Two uses: common settings, common accumulator
    c_n_counter : int = 0

    @staticmethod
    def increment() -> int:
        Cl_static_parameter_standalone.c_n_counter += 1
        return Cl_static_parameter_standalone.c_n_counter
    
class Cl_some_class:

    class Cl_static_parameter_inherited(Cl_static_parameter_standalone):
        pass

    class Cl_static_parameter_nested:
        c_n_counter : int = 0

        @staticmethod
        def increment() -> int:
            Cl_static_parameter_nested.c_n_counter += 1
            return Cl_static_parameter_nested.c_n_counter

    def __init__(self):
        return

    def do_something(self):
        
        print(f"Execute Standalone: {Cl_static_parameter_standalone.increment()}")
        print(f"Execute Inherited: {self.Cl_static_parameter_inherited.increment()}")
        print(f"Execute Nested: {self.Cl_static_parameter_nested.increment()}")
        return

my_instance = Cl_some_class()
my_instance.do_something()

Output:

Execute Standalone: 1
Execute Inherited: 2      
Traceback (most recent call last):
  File "stack_overflow_class_static_parameter.py", line 52, in <module>
    my_instance.do_something()
    ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "stack_overflow_class_static_parameter.py", line 48, in do_something
    print(f"Execute Nested:{self.Cl_static_parameter_nested.increment()}")   
                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^      
  File "stack_overflow_class_static_parameter.py", line 38, in increment
    Cl_static_parameter_nested.c_n_counter += 1     
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
NameError: name 'Cl_static_parameter_nested' is not defined. Did you mean: 'Cl_static_parameter_standalone'?

Solution

  • You can use the classmethod decorator, which is more appropriate for this situation anyways:

    class C:
        class Nested:
            counter = 0
    
            @classmethod
            def increment(cls) -> int:
                cls.counter += 1
                return cls.counter
    
    print(C().Nested.increment())  # prints 1
    

    If you are wondering why increment can't find Cl_static_parameter_nested in your example: you would have to write Cl_some_class.Cl_static_parameter_nested to access it from the global namespace.