1. 程式人生 > >Werkzeug庫:local模塊

Werkzeug庫:local模塊

for ots port ora one obj elf object 獲取

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}

  

Werkzeug庫:local模塊