Как экстернализовать декоратор в приложении Python Flask
Я написал приложение на Python Flask, в котором есть класс и методы, как показано ниже.
class PythonSample:
def method1():
pass # does something
def method2():
pass # does something
Теперь я написал еще один класс, который имеет функции декоратора, как показано ниже.
class PythonAuth:
def oauthAuth():
pass
Теперь я подключаю декоратор oauthAuth для всех методов класса PythonSample, как показано ниже.
import oauthAuth from PythonAuth
class PythonSample
@oauthAuth
def method1():
pass # does something
@oauthAuth
def method2():
pass # does something
Применение декоратора для каждого метода работает нормально.
Вопрос: Вместо того, чтобы применять декоратор oauthAuth к каждому из методов. Есть ли способ настроить в python, применив декоратор oauthAuth ко всем методам в классе и исключив определенные методы.
Что-то вроде включения аутентификации для определенных URL-адресов и исключения аутентификации для определенных URL-адресов
Не обращайте внимания на синтаксис кода Python здесь.
1 ответ
Вы можете использовать декоратор классов плюс немного магии.
Функции украшения
Предположим, у вас есть декоратор, который просто записывает строку перед вызовом функции.
def log(func):
def logged_func(*args, **kwargs):
print('logged')
func(*args, **kwargs)
return logged_func
Декорирование классов
Вы можете использовать тот же прием, но с классом. log_all
декоратор класса, cls
это тип класса. Мы используемvars
ходить по словарю классов и искать методы, используя callable(v)
. Украсить методlog(v)
и использовать setattr
изменить cls
определение к новому декорированному методу. Как и декораторы функций, возвращайте класс в конце.
def log_all(cls):
for k, v in vars(cls).items():
if callable(v):
setattr(cls, k, log(v))
return cls
Я игнорирую k
по сути, но k
- это имя метода, вы можете использовать его для реализации своего сценария использования.
Полный код
Вот полный пример, который теперь должен иметь смысл.
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
Каждый метод в классе A
должен быть украшен log
декоратор.
>>> a = A()
>>> a.method()
logged