2012-06-05 31 views
5

我有一個名爲Server的類可以啓動和停止。除非啓動服務器,否則不應調用某些方法,在這種情況下應引發NotConnectedException。有沒有辦法在類中的每個方法之前調用方法,並確定類變量_started是否設置爲True?在方法調用之前檢查條件

我試過使用裝飾器,但裝飾器函數沒有訪問類變量。我試圖做這樣的事情:

class Server(object): 
    _started = False 
    def started(self): 
     if(self._started == False): 
      raise NotConnectedException 

    @started 
    def doServerAction(self): 
     ... 
+0

你是否嘗試將裝飾器直接放入類中?我還沒有在裝飾器上工作足夠多,知道這會工作,但它是我開始尋找 – inspectorG4dget

+0

這個[post](http://stackoverflow.com/questions/2366713/can-a-python-decorator-如果它是python2.6或更高版本,那麼你的裝飾器可以訪問類變量 – xvatar

+0

@ inspectorG4dget是的,裝飾器在類中。 – BlueVoid

回答

8

記住裝飾

@decorate 
def foo(...): 
    ... 

完全等同於:

def foo(...): 
    ... 
foo = decorate(foo) 

的裝飾是呼籲功能,所以調用第一個參數self會使no感。此外,裝飾器在定義時會在函數上調用,並且它返回的內容將用於代替函數。因此,即使您的started修飾器沒有通過嘗試訪問函數的_started屬性拋出AttributeError,它也會返回None,從而使您的所有方法都設置爲None,因此甚至不能被調用。

你需要的是這樣的:

import functools 

def started(func): 
    @functools.wraps(func) 
    def wrapper(self, *args, **kwargs): 
     if not self._started: 
      raise ... 
     else: 
      return func(self, *args, **kwargs) 
    return wrapper 

幾乎所有的裝飾都是這種形式;他們接受一個函數,創建一個包裝器,對收到的函數執行一些操作,然後返回包裝器。如果您最終在交互式解釋器會話中使用此代碼,則在這裏使用functools.wraps是一種方便;它會使用原始函數的名稱和文檔字符串自動更新wrapper函數,這使裝飾後的函數看起來更像原始函數。

這是否在班級內部定義並不重要。

+0

這正是我所期待的。謝謝! – BlueVoid

相關問題