Подтвердить что ты не робот

Как я могу определить метод декоратора внутри класса?

Возможный дубликат:
Может ли метод класса быть декоратором?

здесь пример.

class myclass:
    def __init__(self):
        self.start = False

    def check(self):
        return not self.start

    def doA(self):
        if self.check():
            return
        print('A')

    def doB(self):
        if self.check():
            return
        print('B')

как вы видите, я хочу написать действие проверки в стиле декоратора, но после того, как я много раз пробовал, я обнаружил, что могу написать метод за пределами моего класса. Попробуйте научить меня, как писать его внутри класса, спасибо

изменить:

Я могу написать код следующим образом:

def check(func):
    def checked(self):
        if not self.start:
            return
        func(self)
    return checked

class myclass:
    def __init__(self):
        self.start = False

    @check
    def doA(self):
        print('A')

    @check
    def doB(self):
        print('B')


a = myclass()

a.doA()
a.doB()

a.start = True

a.doA()
a.doB()

но я не думаю, что это хорошая практика, я хочу определить метод проверки внутри моего класса.

4b9b3361

Ответ 1

Итак, вы хотите использовать декораторы внутри класса на одном (или более) методах членов?

Если это так, я понимаю, чего вы хотите, я не понимаю, зачем вам это нужно?

Нет никаких веских причин для этого. a class - это аккуратный контейнер, вам не нужны декораторы, как методы класса, которые вы можете просто вызвать один метод из другого. Это случай увлеченности decorators?

Ответ 2

В то время как я не думаю, что это абсолютно необходимо все время, вот как вы могли бы сделать декоратор в своем классе. Это немного более громоздко из-за того, как методы впоследствии привязаны к self. Обычно с декораторами с обычными функциями вам не нужно беспокоиться об этом.

Требования:

  • Декоратор должен быть определен первым, прежде чем методы, которые будут его использовать.
  • Для правильного сохранения связанных методов необходимо использовать functools.wrap

Пример:

from functools import wraps

class myclass:
    def __init__(self):
        self.start = False

    def _with_check(f):
        @wraps(f)
        def wrapped(inst, *args, **kwargs):
            if inst.check():
                return
            return f(inst, *args, **kwargs)
        return wrapped

    def check(self):
        return self.start

    @_with_check
    def doA(self):
        print('A')

    @_with_check
    def doB(self):
        print('B')

Я сделал его защищенным членом, так как на самом деле это не то, что кому-то еще нужно использовать за пределами класса. И он по-прежнему сохраняет ваш общедоступный вызов check() для использования сам по себе. Декоратор просто обертывает его вызовом перед вызовом целевого метода.

Ответ 3

Если вам нужно изменить количество или все методы в классе, но вы хотите применить это изменение поведения к этому классу и его подклассам, просто используйте __getattr__() и/или __getattribute__() для вместо этого выполните свое поведение.

Ответ 4

Я думаю, это то, о чем вы просите. Размещение декоратора @property до проверки def (тот же отступ) делает так, чтобы вы могли получить доступ к вычисленному значению проверки() в качестве проверки атрибута, а затем изменить свои методы doA()/doB(), чтобы self.check выглядит как доступ к атрибуту.

class myclass:
    def __init__(self):
        self.start = False

    @property
    def check(self):
        return not self.start

    def doA(self):
        if self.check:
            return
        print('A')

    def doB(self):
        if self.check:
            return
        print('B')