Let's say we have multiple functions which all accept an URL as their first argument and this URL needs to be validated. This can be nicely solved with a decorator
def validate_url(f):
def validated(url, *args, **kwargs):
assert len(url.split('.')) == 3 # trivial example
return f(url, *args, **kwargs)
return validated
@validate_url
def some_func(url, some_other_arg, *some_args, **some_kwargs):
pass
This approach will work and allow me to factor the validation behavior out of many instances of similar functions. But now I would want to write a class method which also takes a validated URL. However, the naive approach will not work
class SomeClass:
@validate_url
def some_method(self, url, some_other_args):
pass
because we will end up attempting to validate self
and not url
. My question is how to write a single decorator which will work for both functions and methods with the minimum amount of boilerplate.
Note 1: I am aware why this happens, it's just that I don't know how to work around this in the most elegant manner.
Note 2: The URL validation problem is just an example, so checking if isinstance(args[0], str)
is not a good solution.