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"