2014-01-27 1 views
2

У меня есть класс, где у меня есть несколько методов. Я хочу использовать один из методов в качестве декоратора для других методов. Для этого я использую следующий синтаксис:Метод класса в качестве декоратора

@self.action 
def execute(self,req):  

, где действие - это другой метод в моем классе. Но это не работает, и бросает исключение, как

name 'self' is not defined 
+0

К моменту создания и декорирования функции экземпляр (даже класс) еще не существует, поэтому вы не можете сделать это так. Что может быть сделано вместо этого, зависит от того, что должно делать «действие». – bereal

+0

action - метод базового класса. Существует много производных классов, и каждый производный класс имеет метод, который выполняет определенную операцию. До и после каждой операции мне нужно выполнить определенные операции, которые я написал в методах базового класса. Но в каждом производном классе я должен повторить этот код. Таким образом, я создал метод, называемый действием в базовом классе, который будет действовать как декоратор. – gliese581g

+0

@ gliese581g: Требуется ли декоратору знать, на каком классе определяется метод? –

ответ

7

Вы не можете использовать метод класса при определении его; в классе нет self, а класс «испечен» еще доступен даже для любого класса.

можно рассматривать методы, как функции для использования в качестве декоратора:

class SomeClass(): 
    def action(func): 
     # decorate 
     return wrapper 

    @action 
    def execute(self, req): 
     # something 

Если action определен на базовый класс, то вы должны указать имя с помощью базового класса:

class Base(): 
    @staticmethod 
    def action(func): 
     # decorate 
     return wrapper 

class Derived(Base): 
    @Base.action 
    def execute(self, req): 
     # something 

Для Python 2 вам понадобится статический метод action, так как в противном случае вы получите несвязанный метод, который будет жаловаться на то, что вы не можете вызвать его без экземпляра в качестве первого аргумента. В Python 3 вы можете оставить там декоратор @staticmethod, по крайней мере, для декоратора.

Но учтите, что action не может использоваться в качестве метода непосредственно; возможно, это не должно быть частью класса вообще в этот момент. Он не является частью API конечных пользователей здесь, по-видимому, декоратор не используется потребителями экземпляров этих классов.

+0

Устранение проблемы того, должно ли 'action' быть частью класса,' action' можно было бы определить как статический метод ('@staticmethod def action (func) ...'). – chepner

+0

@chepner: конечно, но это не делает статический метод более полезным. –

0

В python «self» передается методам экземпляра в качестве аргумента (первый), «я» - это просто условное обозначение, которое можно назвать «foobarbaz» (конечно, это было бы глупо) ... дело в том, что , извне «я» не определяется (поскольку его область действия является методом) ... вы не можете украшать методы класса другими методами класса, вместо этого вам нужно написать отдельный класс!