2012-11-14 89 views
1

我試圖定義在這個類的實例的類,使用方法在包裝功能是否有可能在Python中使用實例方法

下面是工作

代碼裝飾類的方法
class A(object): 
    def __init__(self):  
     pass  

    @self_decorator 
    def to_be_decorated(self): 
     pass  

def self_decorator(fn):  
    from functools import wraps 
    @wraps(fn)  
    def wrapper(*args, **kwargs): 
     self = args[0]  
     return self.app.route('/twip')(fn(*args, **kwargs)) 

    return wrapper 

我居然試圖獲得:

class A(object): 
    def __init__(self):  
     self.app = APP()  

    @self.app.wrapper_function # which apparently doesn't work 
    def to_be_decorated(self): 
     pass 

因此,有可能是我的裝飾工作的方式嗎?

回答

2

在類定義中,沒有自我,因爲類尚不存在,無法實例化。

您可以使用

class A(object): 
    app = APP() 

    @app.wrapper_function 
    def to_be_decorated(self): 
     pass 

但是,這將是一個類變量。

+0

對不起,我給了一個錯誤的例子。我已更新 – yegle

+0

@yegle我也更新了 – JBernardo

0

裝飾器只是一個在定義時被調用的函數。

當你這樣寫:

@self.app.wrapper_function # which apparently doesn't work 
def to_be_decorated(self): 
    pass 

這是大致相同,寫這個:

def to_be_decorated(self): 
    pass 
to_be_decorated = self.app.wrapper_function(to_be_decorated) 

一旦你看到這樣的說法,這是顯而易見的,爲什麼這不工作,和couldn」可能工作。

首先,A的類定義沒有自變量,A也沒有可以訪問的成員app,即使它有。相反,A的每個實例都將擁有自己的唯一self.app

即使你希望口譯員能夠「做我的意思」,如果你仔細想想,那並不意味着什麼。你想調用「the」self.app.wrapper_function方法,但沒有這樣的事情。除非您仔細閱讀所有相關代碼,否則該方法可能會被定義或重新定義,因此絕對不能保證來自A的不同實例的self.app.wrapper_function甚至會具有相同的基礎func_code。但是,即使他們這樣做了,self.app.wrapper_function也是一種綁定方法 - 一種方法與它所調用的對象綁定在一起 - 所以它們仍然彼此不同。

有很多解決這個辦法,但他們都將是同樣的伎倆:用某種間接的得到的函數,而不是self.appself成員,並在調用時引用self.app 。這基本上就是你的self_decorator所做的,這是不可避免的。

相關問題