Werkzeug庫:local模組
阿新 • • 發佈:2018-12-06
1、協程greenlet
from greenlet import greenlet from greenlet import getcurrent def t1(): print(12,getcurrent()) gr2.switch() print(34,getcurrent()) gr2.switch() def t2(): print(56,getcurrent()) gr1.switch() print(78,getcurrent()) gr1 = greenlet(t1) #啟動一個攜程 gr2 = greenlet(t2) gr1.switch()
這裡建立了兩個greenlet協程物件,gr1和gr2,分別對應於函式test1()和test2()。使用greenlet物件的switch()方法,即可以切換協程。上例中,我們先呼叫”gr1.switch()”,函式test1()被執行,然後打印出”12″;接著由於”gr2.switch()”被呼叫,協程切換到函式test2(),打印出”56″;之後”gr1.switch()”又被呼叫,所以又切換到函式test1()。但注意,由於之前test1()已經執行到第5行,也就是”gr2.switch()”,所以切換回來後會繼續往下執行,也就是列印”34″;現在函式test1()退出,同時程式退出。由於再沒有”gr2.switch()”來切換至函式test2(),所以程式第11行”print 78″不會被執行。
getcurrent()用來獲取協程的id。
2、使用greenlet實現為每個協程開闢資料儲存空間
2.1、為每個協程開闢資料儲存空間
原始碼:
from greenlet import getcurrent as get_ident from greenlet import greenlet # 釋放Local類例項化物件local中該協程儲存在local.__storage__中key為self.__ident_func__()的資料 def release_local(local): local.__release_local__() class Local(object): __slots__ = ('__storage__', '__ident_func__') def __init__(self): # 設定類Local的物件l的屬性__storage__為空字典 object.__setattr__(self, '__storage__', {}) # 設定類Local的物件l的屬性__ident_func__為get_ident方法,get_ident()可以獲取協程的id號 object.__setattr__(self, '__ident_func__', get_ident) # 將類Local物件l內所有協程的資料生成一個生成器返回 def __iter__(self): return iter(self.__storage__.items()) # 釋放該協程中儲存的資料空間 def __release_local__(self): self.__storage__.pop(self.__ident_func__(), None) # 獲取該協程中儲存的key為name的資料 def __getattr__(self, name): try: return self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name) # 將name作為key,value作為value存入該協程中的資料空間中 def __setattr__(self, name, value): ident = self.__ident_func__() storage = self.__storage__ try: storage[ident][name] = value except KeyError: storage[ident] = {name: value} # 刪除該協程中儲存的key為name的資料 def __delattr__(self, name): try: del self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name) l = Local() def t1(): # 將資料a=1 ,A=3存入協程gr1中 l.a = 1 l.A = 3 print("攜程a:%s" % get_ident(), l.a) gr2.switch() def t2(): # 將資料b=2 ,B=4存入協程gr2中 l.b = 2 l.B = 4 print("攜程b:%s" % get_ident(), l.b) gr1.switch() # 將資料m=8 ,M=8存入預設生成的協程中(可以看做主協程) l.m = 8 l.M = 8 print("攜程m:%s" % get_ident(),l.m) gr1 = greenlet(t1) #啟動一個攜程 gr2 = greenlet(t2) gr1.switch() print("攜程m:%s" % get_ident(), l.m) for k,v in l.__storage__.items(): print("%s:%s"%(k,v))
執行結果:
攜程m:<greenlet.greenlet object at 0x01E25558> 8 攜程a:<greenlet.greenlet object at 0x01E25500> 1 攜程b:<greenlet.greenlet object at 0x01E25BE0> 2 攜程m:<greenlet.greenlet object at 0x01E25558> 8 <greenlet.greenlet object at 0x01E25558>:{'m': 8, 'M': 8} <greenlet.greenlet object at 0x01E25500>:{'a': 1, 'A': 3} <greenlet.greenlet object at 0x01E25BE0>:{'b': 2, 'B': 4}
2.2、在協程執行完後釋放資料儲存空間
原始碼:
from greenlet import getcurrent as get_ident from greenlet import greenlet # 釋放Local類例項化物件local中該協程儲存在local.__storage__中key為self.__ident_func__()的資料 def release_local(local): local.__release_local__() class Local(object): __slots__ = ('__storage__', '__ident_func__') def __init__(self): # 設定類Local的物件l的屬性__storage__為空字典 object.__setattr__(self, '__storage__', {}) # 設定類Local的物件l的屬性__ident_func__為get_ident方法,get_ident()可以獲取協程的id號 object.__setattr__(self, '__ident_func__', get_ident) # 將類Local物件l內所有協程的資料生成一個生成器返回 def __iter__(self): return iter(self.__storage__.items()) # 釋放該協程中儲存的資料空間 def __release_local__(self): self.__storage__.pop(self.__ident_func__(), None) # 獲取該協程中儲存的key為name的資料 def __getattr__(self, name): try: return self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name) # 將name作為key,value作為value存入該協程中的資料空間中 def __setattr__(self, name, value): ident = self.__ident_func__() storage = self.__storage__ try: storage[ident][name] = value except KeyError: storage[ident] = {name: value} # 刪除該協程中儲存的key為name的資料 def __delattr__(self, name): try: del self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name) l = Local() def t1(): l.a = 1 l.A = 3 print("攜程a:%s" % get_ident(), l.a) gr2.switch() release_local(l) print("攜程a:%s||是否有l.a:" % get_ident(), hasattr(l, 'a')) gr2.switch() def t2(): l.b = 2 l.B = 4 print("攜程b:%s" % get_ident(), l.b) gr1.switch() release_local(l) print("攜程b:%s||是否有l.b:" % get_ident(), hasattr(l, 'b')) # 將資料m=8 ,M=8存入預設生成的協程中(可以看做主協程) l.m = 8 l.M = 8 print("攜程m:%s" % get_ident(),l.m) gr1 = greenlet(t1) #啟動一個攜程 gr2 = greenlet(t2) gr1.switch() print("攜程m:%s" % get_ident(), l.m) for k,v in l.__storage__.items(): print("%s:%s" % (k, v))
執行結果:
攜程m:<greenlet.greenlet object at 0x00635608> 8 攜程a:<greenlet.greenlet object at 0x006355B0> 1 攜程b:<greenlet.greenlet object at 0x00635558> 2 攜程a:<greenlet.greenlet object at 0x006355B0>||是否有l.a: False 攜程b:<greenlet.greenlet object at 0x00635558>||是否有l.b: False 攜程m:<greenlet.greenlet object at 0x00635608> 8 <greenlet.greenlet object at 0x00635608>:{'m': 8, 'M': 8}