I have an issue where I'm trying to create a simple Class decorator which checks for passed variables presence (that is they're not None). Problem is, this is done inside another class, so the checked variables are from self.
. Basically I'm trying to create a wrapper which iterates over given self variables and checks if they're not None.
class CheckForVariablesPresence:
"""Wrapper for checking if given variable(s) are not None.
"""
def __init__(self, *variables):
self.variables = variables
def __call__(self, func):
@wraps(func)
def wrapper(*args, **kwargs):
for variable in self.variables:
if variable is None:
raise KeyError(
"Variable not found.\n",
"Run the appropriate method first.",
)
return func(*args, **kwargs)
The thing is, I can't pass self.variable
in the method's decorator, as self isn't even yet created.
@CheckForVariablesPresence(self.variable)
def __repr__(self):
return str(self.variable)
Any ideas how I could do this differently (and better)? I started with one function for checking the exact variable, but the variables checked are growing and depend on each and different method I'm calling, thus the reason I wanted to use a wrapper which could iterate over them.
Self answer: This idea of doing this in that way is quite bad - as pointed out by @chepner in the comments. Although I think he meant doing something else, I resolved it in another way (due to limitations of how it had to work because of another module). Basically the __getattr__
method is what I was looking for and I've implemented a custom AttributeError
message for when the attribute that's available, but not yet initialised, was called.
This is a sample.
def __getattr__(self, name: str):
value = self.__dict__.get(name)
if value is None and name in self.__available_attributes:
raise AttributeError(
f"Attribute {name} not found. Run the appropriate method first or set it."
)
elif value is None:
raise AttributeError(f"{self.__class__.__name__}.{name} is invalid")
return value