Как экстернализировать декоратор в приложении python flask - PullRequest
0 голосов
/ 02 октября 2019

Я написал приложение 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 decorator ко всем методам в классе и исключить определенные методы.

Что-то вроде включения аутентификации для определенных URL-адресов и исключения аутентификации для определенных URL-адресов

Пожалуйста, игнорируйте синтаксис кода Python здесь.

1 Ответ

0 голосов
/ 02 октября 2019

Вы можете использовать декоратор класса плюс немного магии.

Функции декорации

Предположим, у вас есть декоратор, который просто записывает строку в журнал перед вызовом функции.

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
...