Как экстернализовать декоратор в приложении 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
Другие вопросы по тегам