Werkzeug原始碼閱讀筆記 三

2022-07-20 19:00:14 字數 4474 閱讀 4242

這次主要講下werkzeug中的local. 原始碼在werkzeug/local.py

在python中,狀態是儲存在物件中。thread local是一種特殊的物件,它是對執行緒隔離的。所謂對執行緒隔離,是指每乙個執行緒對乙個thread local物件進行修改,是不會影響到其他執行緒的。這就好比在工作單位每個人都有乙個儲物櫃,每個人對自己的儲物櫃訪問東西是不會影響到其他人的。這裡的儲物櫃就是thread local.

獲得乙個thread local很簡單,只需要對執行緒執行local():threading.local()

werkzeug的原始碼中,local()類的實現比較簡單,只是定義了幾個特殊函式。檔案在werkzeug/local.py

在該檔案中,還定義了release_local(local)方法,用來釋放local物件. 同時,在local()類中實現了__release_local__()函式,它包裹了release_local(local)函式,呼叫__release_local__()可以釋放當前local物件

在werkzeug中同時實現了localstack這個類,它包含了local()類的例項,實現了local的棧結構,以下是重要部分的**:

class localstack(object):

def __init__(self):

self._local = local() #localstack中有個local類的物件

def __release_local__(self): #定義釋放當前local物件的方法

self._local.__release_local__()

def _get__ident_func__(self):

return self._local.__ident_func__

def _set__ident_func__(self, value):

object.__setattr__(self._local, '__ident_func__', value)

__ident_func__ = property(_get__ident_func__, _set__ident_func__)

del _get__ident_func__, _set__ident_func__

def __call__(self):

def _lookup():

rv = self.top

if rv is none:

raise runtimeerror('object unbound')

return rv

return localproxy(_lookup)

def push(self, obj):

"""pushes a new item to the stack"""

rv = getattr(self._local, 'stack', none)

if rv is none:

self._local.stack = rv =

return rv

def pop(self):

stack = getattr(self._local, 'stack', none)

if stack is none:

return none

elif len(stack) == 1:

release_local(self._local)

return stack[-1]

else:

return stack.pop()

@property

def top(self):

try:

return self._local.stack[-1]

except (attributeerror, indexerror):

return none

所有對該物件的修改,只對本執行緒可見

在werkzeug中還定義了本地**。localproxy是典型的**模式的實現。它在構造的時候接受乙個callable的引數(實現了__call__()方法的類,乙個函式等),這個引數被呼叫後的返回值本身是乙個thread local物件。對乙個localproxy物件的所有操作都會**到那個callable引數返回的thread local物件上。

這是localproxy的初始化函式:

def __init__(self, local, name=none):

object.__setattr__(self, '_localproxy__local', local)

object.__setattr__(self, '__name__', name)

可以看到,該函式中有個local引數,這個引數就是callable引數。

下面是local類中的__call__()函式

def __call__(self, proxy):

"""create a proxy for a name."""

return localproxy(self, proxy)

比如執行:

l = local()

request = l('request')

這時候就會呼叫__call__()函式,request = l('request')相當於執行:

request = localproxy(l, 'request')
這時候request就是乙個localproxy物件,自動呼叫初始化函式,該物件有兩個元素:_localproxy__local(等於l)和__name__(等於'request')

所以,對request的操作會返還給l進行實際操作

同時注意到localstack類也實現了__call__()函式,同樣可以當做local引數.

localstack中的__call__函式:

def __call__(self):

def _lookup():

rv = self.top

if rv is none:

raise runtimeerror('object unbound')

return rv

return localproxy(_lookup)

執行:

_response_local = localstack()

response = _response_local()

這時候response就是乙個localproxy,自動呼叫初始化函式,該物件有兩個元素:_localproxy__local(等於_lookup函式)和__name__(等於none)

localproxy類中,還實現了乙個重要的方法:_get_current_object():

def _get_current_object(self):

if not hasattr(self.__local, '__release_local__'):

return self.__local()

try:

return getattr(self.__local, self.__name__)

except attributeerror:

raise runtimeerror('no object bound to %s' % self.__name__)

這個方法的作用是獲得該localproxy物件背後的真正的物件

在該檔案中,還實現了localmanager這個類. 因為local物件不能管理自身,所以可能需要乙個localmanager物件,可以把多個local物件傳給localmanager物件,該物件的每一次清理操作就會清理掉當前上下文中的local物件

具體的類方法很簡單,就不一一贅述了

WERKZEUG之WSGI閱讀筆記

pep3333指出,wsgi web server gateway inte ce 是web伺服器和web框架或web應用之間建立的一種簡單通用的介面規範。有了wsgi這份介面規範,在web開發的過程中,能更加自由的選擇伺服器端和框架 在伺服器端和框架的開發過程能夠分離開來,不用過多的考慮雙方具體的...

閱讀筆記 fsnotify原始碼閱讀

fsnotify的github位址是 fsnotify是乙個資料夾監控應用。可以使用建立乙個watcher來對某個資料夾進行監控 檔案目錄很簡單,實際就兩個程式檔案,fsnotify.go 和 各平台的fsnotify go 後乙個檔案是各個不同平台的實現 example test.go中給的是最簡...

《原始碼閱讀》原始碼閱讀技巧,原始碼閱讀工具

檢視某個類的完整繼承關係 選中類的名稱,然後按f4 quick type hierarchy quick type hierarchy可以顯示出類的繼承結構,包括它的父類和子類 supertype hierarchy supertype hierarchy可以顯示出類的繼承和實現結構,包括它的父類和...