Reputation: 107
I have written a python Flask application, which has a class and methods as below.
class PythonSample:
def method1():
pass # does something
def method2():
pass # does something
Now I have written another class which has decorator functions as below.
class PythonAuth:
def oauthAuth():
pass
Now I'm wiring oauthAuth decorator for all the methods of PythonSample class as below
import oauthAuth from PythonAuth
class PythonSample
@oauthAuth
def method1():
pass # does something
@oauthAuth
def method2():
pass # does something
Applying decorator at each method works fine.
Question: Instead of applying oauthAuth decorator to each of the methods. Is there a way to configure in python, as apply oauthAuth decorator to all the methods in a class and exclude certain methods.
Something like include auth for certain URLs and exclude authentication for certain urls
Please ignore the syntax of the python code here.
Upvotes: 0
Views: 108
Reputation: 2648
You can use a class decorator plus some magic.
Assume you have a decorator that just logs a string before calling the function.
def log(func):
def logged_func(*args, **kwargs):
print('logged')
func(*args, **kwargs)
return logged_func
You can use the same trick, but with a class. log_all
is a class decorator, cls
is a class type. We use vars
to walk the class dictionary, and look for methods by using callable(v)
. Decorate the method with log(v)
and use setattr
to change the cls
definition to the new decorated method. Just like function decorators, return the class in the end.
def log_all(cls):
for k, v in vars(cls).items():
if callable(v):
setattr(cls, k, log(v))
return cls
I am ignoring k
essentially, but k
is the method name, you could leverage it to achieve your usage scenario.
Here is a full example, that should make some sense now.
def log(func):
def logged_func(*args, **kwargs):
print('logged')
func(*args, **kwargs)
return logged_func
def log_all(cls):
for k, v in vars(cls).items():
if callable(v):
setattr(cls, k, log(v))
return cls
@log_all
class A:
def method(self):
pass
Every method in class A
should be decorated with the log
decorator.
>>> a = A()
>>> a.method()
logged
Upvotes: 0