1

I have a class which is used to hold a bunch of python static methods which will return a string from an environment variable.

class GitLabCiEnv():
    """
    Gitlab CI Environment variables.
    """
    @staticmethod
    def CHAT_CHANNEL() -> str:
        """
        Source chat channel which triggered the ChatOps command.

        Added in GitLab 10.6
        Available in GitLab Runner all
        """
        return os.environ["CHAT_CHANNEL"]

    @staticmethod
    def CHAT_INPUT() -> str:
        """
        Additional arguments passed in the ChatOps command.

        Added in GitLab 10.6
        Available in GitLab Runner all
        """
        return os.environ["CHAT_INPUT"]

With this class I can just call GitLabCiEnv.CHAT_CHANNEL() to get the value of the environment variable. The "ugly" is, that I have to use paranthesis for each those @staticmethod. What I would do is GitLabCiEnv.CHAT_CHANNEL without paranthesis.

I do not want to instantiate an object of this class, there is, in my opinion no benefit of having an object. I tried different implementations, using class variables, but then each variable will be initialized if the class is imported, this is not what i want.

Maybe someone has a solution for me.

Thank you very much!

dvonessen
  • 177
  • 1
  • 8
  • use classmethod ? – sahasrara62 Mar 02 '21 at 18:12
  • 5
    "in my opinion no benefit of having an object" Correct. In fact, there is also no benefit of having a class as there does not seem to be any state that needs to be tracked. These methods should probably just be a module-level functions – DeepSpace Mar 02 '21 at 18:12
  • 4
    "I have a class which is used to hold a bunch of python static methods" that is something that shouldn't be a class then. Probably just a module with functions – juanpa.arrivillaga Mar 02 '21 at 18:21
  • Yes I thought about the "module with functions" but then, I wouldn't get rid of the parentheses. Because the return values are more ore less "static/constant" I want, that the enduser (who uses this class) has an interface as simple as possible. Maybe if someone would give me an example how to implement it in other ways I will check it. – dvonessen Mar 03 '21 at 06:33

1 Answers1

3

This probably shouldn't be a class. But if you really want this, just create a custom descriptor:

import os

class EnvProxy:
    def __init__(self, key):
        self.key = key
    def __get__(self, obj, objtype=None):
        return os.environ[self.key]

class GitLabCiEnv:
    CHAT_CHANNEL = EnvProxy("CHAT_CHANNEL")
    CHAT_INPUT = EnvProxy("CHAT_INPUT")

An example:

(py38) juanarrivillaga@50-254-139-253-static Project-Roche-2 % CHAT_INPUT=foo python -i test.py
>>> GitLabCiEnv.CHAT_INPUT
'foo'
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172