Waqas Kayani
Waqas Kayani

Reputation: 151

Use project config variables across different Python scripts

I am working on a project with multiple directories, each having a number of python scripts. And it involves use of certain key parameters I pass using a yaml config file.

Currently the method used is, (I'd say it is naive as) it simply parses the yaml to a python dictionary, which is then imported in other scripts and values are accessed.

From what I could find, there is:

  1. Abseil library that can be used for accessing flags across different scripts but using it is cumbersome.
  2. Another approach using a Class (preferably singleton), putting all global variables in it and exposing instance of that class in other scripts.

I wanted to ask, is there any other library that can be used for this purpose? And what is the most pythonic methodolgy to deal with it?

Any help would be really appreciated. Thanks!

Upvotes: 0

Views: 925

Answers (1)

AUNZ
AUNZ

Reputation: 58

To make global values accessible across modules I use the Class (singleton) Method.

The code I list below is also in my Gisthub https://gist.github.com/auphofBSF/278206afff675cd30377f4894a5b2b1d

My generic GlobalValues singleton class and usage is as follows. This class is located in a subdirectory below the main. In the example of use that I also attach I place the GlobalValues class in a file globals.py in the folder myClasses

class GlobalValues:
    """
    a Singleton class to serve the GlobalValues
    USAGE: (FirstTime)
    from myClasses.globals import GlobalValues
    global_values = GlobalValues()
    global_values.<new value> = ...
    ... = global_values.<value>

    USAGE: (Second and n'th time, in same module or other modules)
        NB adjust `from myClasses.globals` dependent on relative path to this module 
    from myClasses.globals import GlobalValues 
    global_values = GlobalValues.getInstance()
    global_values.<new value> = ...
    ... = global_values.<value>


    """
    __instance = None
    DEFAULT_LOG_LEVEL="CRITICAL"

    @staticmethod
    def get_instance():
        """ Static access method. """
        if GlobalValues.__instance == None:
            GlobalValues()
        return GlobalValues.__instance
    def __init__(self):
        """ Virtually private constructor. """
        if GlobalValues.__instance != None:
            raise Exception("This class is a singleton! once created use global_values = Glovalvalues.get_instance()")
        else:
            GlobalValues.__instance = self

my Example of use is as follows

Example File layout

        <exampleRootDir>
            Example_GlobalValues_Main.py  #THIS is the main 
            myClasses # A folder
                globals.py #for the singleton class GlobalValues 
                exampleSubModule.py # demonstrates use in submodules

Example_GlobalValues_Main.py

print(
    """ 
        ----------------------------------------------------------
        Example of using a singleton Class as a Global value store
        The files in this example are in these folders

        file structure:
        <exampleRootDir>
            Example_GlobalValues_Main.py  #THIS is the main 
            myClasses # A folder
                globals.py #for the singleton class GlobalValues 
                exampleSubModule.py # demonstrates use in submodules
        -----------------------------------------------------------
    """
)

from myClasses.globals import GlobalValues

globalvalues = GlobalValues() # THe only place an Instance of GlobalValues is created

print(f"MAIN: global DEFAULT_LOG_LEVEL is {globalvalues.DEFAULT_LOG_LEVEL}")
globalvalues.DEFAULT_LOG_LEVEL = "DEBUG"
print(f"MAIN: global DEFAULT_LOG_LEVEL is now {globalvalues.DEFAULT_LOG_LEVEL}")

#Add a new global value:
globalvalues.NEW_VALUE = "hello"

#demonstrate using global modules in another module
from myClasses import exampleSubModule

print(f"MAIN: globalvalues after opening exampleSubModule are now {vars(globalvalues)}")

print("----------------- Completed -------------------------------")

exampleSubModule.py is as follows and is located in the myClasses folder


"""
Example SubModule using the GlobalValues Singleton Class
"""
# observe where the globals module is in relation to this module . = same directory
from .globals import GlobalValues

# get the singleton instance of GlobalValues, cannot instantiate a new instance
exampleSubModule_globalvalues = GlobalValues.get_instance() 

print(f"exampleSubModule: values in GlobalValues are: {vars(exampleSubModule_globalvalues)}")

#Change a value
exampleSubModule_globalvalues.NEW_VALUE = "greetings from exampleSubModule"  
#add a new value
exampleSubModule_globalvalues.SUBMODULE = "exampleSubModule"

Upvotes: 2

Related Questions