2013-03-04 84 views
4

我有一個類定義如下:Python的裝飾帶參數和訪問類的實例

class SomeViewController(BaseViewController): 
    @requires('id', 'param1', 'param2') 
    @ajaxGet 
    def create(self): 
     #do something here 

是否可以寫一個裝飾功能:

  1. 注意到ARGS的列表,並可能kwargs和
  2. 訪問類裝飾在其中定義的方法的類的實例?

所以對於@ajaxGet裝飾,還有其中包含我需要檢查的值稱爲typeself一個屬性。

謝謝

+1

取決於你的意思。裝飾器本身不能訪問'self',因爲裝飾在類的定義期間發生,在任何實例存在之前。但是作爲裝飾器結果的包裝函數會在調用它時知道實例。你能舉一個你想達到的例子嗎? – BrenBarn 2013-03-04 06:35:04

+0

因此,當我在'SomeViewController'上調用'create'時,裝飾的方法可以訪問'self'(它被傳入'create',因此使用該對象是可能的),並且還可以使用參數來執行檢查針對'self'的其他屬性 – 2013-03-04 06:45:08

回答

9

是的。事實上,從某種意義上說,你似乎並沒有真正的方法來寫出一個裝飾者,並不是有權訪問self。裝飾函數包裝原始函數,所以它必須至少接受該函數接受的參數(或者可以從中派生出一些參數),否則它不能將正確的參數傳遞給底層函數。

沒有什麼特別的,你需要做的,做到這一點,只寫一個普通的裝飾:

def deco(func): 
    def wrapper(self, *args, **kwargs): 
     print "I am the decorator, I know that self is", self, "and I can do whatever I want with it!" 
     print "I also got other args:", args, kwargs 
     func(self) 
    return wrapper 

class Foo(object): 
    @deco 
    def meth(self): 
     print "I am the method, my self is", self 

然後,你可以使用它:

>>> f = Foo() 
>>> f.meth() 
I am the decorator, I know that self is <__main__.Foo object at 0x0000000002BCBE80> and I can do whatever I want with it! 
I also got other args:() {} 
I am the method, my self is <__main__.Foo object at 0x0000000002BCBE80> 
>>> f.meth('blah', stuff='crud') 
I am the decorator, I know that self is <__main__.Foo object at 0x0000000002BCBE80> and I can do whatever I want with it! 
I also got other args: (u'blah',) {'stuff': u'crud'} 
I am the method, my self is <__main__.Foo object at 0x0000000002BCBE80> 
+0

感謝。有沒有辦法讓裝飾參數檢查?如果你能回答我會讓你的答案成爲可接受的答案。 – 2013-03-04 07:32:21

+0

你是什麼意思「帶參數檢查」? – BrenBarn 2013-03-04 07:56:54

+0

裝飾者必須接受一些參數,然後在裝飾器函數中檢查'self'。儘管如此,裝飾器函數必須包裝在另一個函數中。 – 2013-03-04 08:00:15