-2

I've written the following base static class in python:

from abc import ABC,abstractmethod

import typing
from main_module import utils


class BaseCLS(ABC):
    credentials = None # <--- I want to set this var
    def __init_session(caller) -> None:
        credentials = utils.get_creds() # <--- not the right var

    @staticmethod
    @__init_session
    def process(path: str) -> None:
        raise NotImplementedError

The base class private method __init_session is triggered by a decorator each time process is called. I'm trying to set the credentials class var from within the private method with no luck. How can I achieve my goal?

Seon
  • 3,332
  • 8
  • 27
Shlomi Schwartz
  • 8,693
  • 29
  • 109
  • 186
  • 1
    I don't see how you could do this besides simply `BaseCLS.credentials = ...`, since you're using a *static* method, which has no access to either the instance nor the class… – deceze Nov 18 '21 at 09:50
  • Thanks, but I get an error NameError: name 'BaseCLS' is not defined – Shlomi Schwartz Nov 18 '21 at 09:54
  • Err, true, as the decorator is run before the class exists… then I see even less options for this to work as is. Something in this design has to give, and it's unclear what *can* give here. – deceze Nov 18 '21 at 10:04
  • This isn't how decorators work. `@__init_session` doesn't call `__init_session` each time `process` is called. It calls `__init_session` once, when `process` is defined, and passes `process` itself to `__init_session` as the single argument. You should go read up on decorator semantics and techniques. Also, the use of static methods and class variables seems really weird, especially in what seems intended to be an abstract class. – user2357112 Nov 18 '21 at 10:22
  • Also, "base static class" doesn't make sense. I don't know what meaning you were trying to express by using those words in that order, but there's no such thing as a "static class" or "base static class" in Python. – user2357112 Nov 18 '21 at 10:23

1 Answers1

1

If you want to set the class variable in derived classes, the following would work.

from abc import ABC,abstractmethod
import typing
import random

class BaseCLS(ABC):
    credentials = None # <--- I want to set this var

    def __init_session(caller) -> None:
        def inner(cls, path):
            # credentials = utils.get_creds()
            cls.credentials = random.random()
            caller(cls, path)
        return inner

    @classmethod # <--- changed to classmethod
    @__init_session
    def process(cls, path: str) -> None:
      pass

class B(BaseCLS):
  pass

class C(BaseCLS):
  pass


B.process("a")
C.process("b")

print(B.credentials)
print(C.credentials)
Shanavas M
  • 1,581
  • 1
  • 17
  • 24