Skip to content Skip to sidebar Skip to footer

How To Share Variables Across Python Modules When Getter And Setter Methods Are Required

How can I share variables across different modules of my Python project if I need these variables to have setter and getter methods. The reason I need setter\getter methods is beca

Solution 1:

To solve this issue I propose the following code section. It is split into two classes.

The first class is working at the class level and maintains a 2 level nested dictionary that contains the name of the datastore and the variable name.

The second class is the datastore itself. It has the minimum required code to keep it visually simple.

This specific implementation has one known error prone limitation. If you declare two or more variables with the same name in different datastore classes, i.d. you define class FrameworkDatastore and another class SecondDatastore with the same variable in both, the environment will have only one of them.

import inspect
import logging
import os
from typing import Any, Dict, Type

logger = logging.getLogger(__name__)


class_BaseDataStoreWithEnvironSupport:"""
    The class support global storing of variables in a class level dictionary, allowing all instances of the
    datastore to access the same values.
    This class is backward compatible to store the global variables as os.environ, but also
    """_members: Dict[str, Dict[str, Any]] = {}  # holds all the members of the datastore@classmethoddefget_value(cls) -> Any:datastore_name: str = cls.__name__
        member_name: str = inspect.stack()[1][3]
        env_value: str = os.environ.get(member_name)
        ds_value: Any = cls._members[datastore_name][member_name]

        ifenv_value:type_ds_value: Type = type(ds_value)
            if type_ds_value is bool:value: bool = (env_value == True.__str__())
            else:value: Any = type(ds_value)(env_value)
            if value != ds_value:
                logger.warning('Environment stored value is different from Datastore value. Check your implementation')
        else:value: Any = ds_value

        return value

    @classmethoddefset_value(cls, value: Any) -> None:datastore_name: str = cls.__name__
        name: str = inspect.stack()[1][3]
        if datastore_name notin cls._members.keys():
            cls._members[datastore_name] = {}
        cls._members[datastore_name][name] = value
        os.environ[name] = str(value)

    defvalidate_datastore(self):
        members = set([attr for attr in dir(self) ifnot callable(getattr(self, attr)) andnot attr.startswith("_")])
        if members.__len__() == 0:
            raise RuntimeError(f'There are no members in the datastore or the validation runs at the start of __init__')

        datastore_name: str = self.__class__.__name__
        dict_keys: set = set(self._members[datastore_name].keys())
        if members != dict_keys:missing_members: set = members - dict_keys
            raise NotImplementedError(f'Datastore is missing get and set methods for members: {missing_members}')


classFrameworkDatastore(_BaseDataStoreWithEnvironSupport):"""
    This class is storing all variables that are currently saved as global or os.environ variables
    If the data stored here becomes irrelevant after the code change or is seldom used, remove it and merge its
    functionality into other sections
    """def__init__(self):
        """
        predefine all the members of the datastore.
        Members which dont implement get/set methods will be flagged by the validate_datastore check
        """self.run_traffic_validations: bool = True  # Should Ixia traffic validations run in the current suite# The validation of the datastore must come at the end of the __init__ methodself.validate_datastore()

    @propertydefrun_traffic_validations(self):
        returnself.get_value()

    @run_traffic_validations.setter
    defrun_traffic_validations(self, value: Any):
        self.set_value(value)


if __name__ == '__main__':
    # This tests the datastore code
    fd1 = FrameworkDatastore()
    fd2 = FrameworkDatastore()
    print(fd1.run_traffic_validations)
    print(fd2.run_traffic_validations)
    fd1.run_traffic_validations = False
    print(fd1.run_traffic_validations)
    print(fd2.run_traffic_validations)
    fd2.run_traffic_validations = True
    print(fd1.run_traffic_validations)
    print(fd2.run_traffic_validations)

Post a Comment for "How To Share Variables Across Python Modules When Getter And Setter Methods Are Required"