Attempting to validate data with a variety of labels used to varying degrees by various objects, I’ve been writing a class to do the validating, storing the function names in an instance dictionary, so that labels needing their values to get the same kind of validation can call the same validating function, however, calling the function via a lookup in the dictionary requires ‘self’ to be supplied as the first argument.
This can be overcome by decorating each function in the class with @staticmethod and removing the ‘self’ argument from it’s declaration, but I’m wondering if there’s a workaround that would simply enable the relevant function to be called as if I was calling it normally from within the instance?
This isn’t the code I’ve been writing, but is a shorter version to demonstrate the dynamic.
It uses a function to return the number of attributes required in each call, depending on the method used to call it, then calls each function via each method.
import inspect
class FunctionRunner:
"""Class to test running functions from a dictionary."""
# The functions
def _func1(self, value: str) -> None:
print(f"Called method _func1 with value {value}.")
def _func2(self, value: str) -> None:
print(f"Called method _func2 with value {value}.")
def _func3(self, value: str) -> None:
print(f"Called method _func3 with value {value}.")
def _func4(self, value: str) -> None:
print(f"Called method _func4 with value {value}.")
# The dictionary containing references to the functions
_func_dictionary = {1: _func1, 2: _func2, 3: _func3, 4: _func4}
# A function to look up a reference and run a function
def run_function(self, func_id: int, value: str) -> None:
# Looking for a workaround to enable me to remove 'self' from this function call
self._func_dictionary[func_id](self, value)
def run_directly(self) -> None:
self._func1("10")
self._func2("20")
self._func3("30")
self._func4("40")
def count_positional_args_required(self, func):
signature = inspect.signature(func)
empty = inspect.Parameter.empty
return sum(param.default is empty for param in signature.parameters.values())
def inspect_functions(self):
for idx in range(1, 5):
print(self.count_positional_args_required(self._func_dictionary[idx]))
print()
print(self.count_positional_args_required(self._func1))
print(self.count_positional_args_required(self._func2))
print(self.count_positional_args_required(self._func3))
print(self.count_positional_args_required(self._func4))
def main():
FR = FunctionRunner()
FR.inspect_functions()
print()
FR.run_function(1, "10")
FR.run_function(2, "20")
FR.run_function(3, "30")
FR.run_function(4, "40")
print()
FR.run_directly()
if "__main__" == __name__:
main()
Thanks in advance for any help, folks!