亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python 中@lazyprop 裝飾器的用法

 更新時間:2021年05月25日 14:40:25   作者:ON_THE_WAY_FOREVER  
這篇文章主要介紹了Python 中@lazyprop 裝飾器的用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

安裝

pip install lazyprop

例子1

from lazyprop import lazyprop
class Foo(object):
    def __init__(self):
        self.load_count = 0
    @lazyprop
    def lazy(self):
        self.load_count += 1
f = Foo()
f.lazy
f.lazy
f.lazy
print(f.load_count)

輸出:

1

例子2

from lazyprop import lazyprop
class Foo(object):
    def __init__(self):
        self.load_count = 0
    # @lazyprop
    def lazy(self):
        self.load_count += 1
f = Foo()
f.lazy
f.lazy
f.lazy
print(f.load_count)

輸出:

0

補充:python語言中的AOP利器:裝飾器

一、前言

面向切面編程(AOP)是一種編程思想,與OOP并不矛盾,只是它們的關注點相同。面向對象的目的在于抽象和管理,而面向切面的目的在于解耦和復用。

舉兩個大家都接觸過的AOP的例子:

1)java中mybatis的@Transactional注解,大家知道被這個注解注釋的函數立即就能獲得DB的事務能力。

2)python中的with threading.Lock(),大家知道,被這個with代碼塊包裹的部分立即獲得同步的鎖機制。

這樣我們把事務和加鎖這兩種與業(yè)務無關的邏輯抽象出來,在邏輯上解耦,并且可以輕松的做到代碼復用。

二、上下文管理器contextlib

當然你可以使用with上下文管理器實現一些AOP的思想,這里有個模塊叫contextlib可以幫助你簡易的實現上下文管理器。

上下文管理最常見的例子是with open('file') as fh,回收打開句柄的例子。

這種方式還是比較麻煩的,下面我們看一下python中的裝飾器怎么樣實現AOP編程。

三、裝飾器:AOP的語法糖

python中的裝飾器就是設計來實現切面注入功能的。下面給出幾個例子,這幾個例子都是在生產環(huán)境驗證過的。

其中的任務管理機是偽代碼,需要自己實現寫數據庫的邏輯。

1、重試邏輯

只要do函數被@retry_exp裝飾,便可以獲得指數退避的重試能力。

@retry_exp(max_retries=10)
def do():
    # do whatever
    pass

那retry_exp是如何實現的呢?

def retry_exp(max_retries=3, max_wait_interval=10, period=1, rand=False):
    def _retry(func):
        def __retry(*args, **kwargs):
            MAX_RETRIES = max_retries
            MAX_WAIT_INTERVAL = max_wait_interval
            PERIOD = period
            RAND = rand
            retries = 0
            error = None
            ok = False
            while retries < MAX_RETRIES:
                try:
                    ret = func(*args, **kwargs)
                    ok = True
                    return ret
                except Exception, ex:
                    error = ex
                finally:
                    if not ok:
                        sleep_time = min(2 ** retries * PERIOD if not RAND else randint(0, 2 ** retries) * PERIOD, MAX_WAIT_INTERVAL)
                        time.sleep(sleep_time)
                        retries += 1
            if retries == MAX_RETRIES:
                if error:
                    raise error
                else:
                    raise Exception("unknown")
        return __retry
    return _retry

2、降級開關

只要do函數被@degrade裝飾,就會安裝app名稱校驗redis里的開關,一旦發(fā)現開關關閉,則do函數不被執(zhí)行,也就是降級。

@degrade
def do(app):
    # do whatever
    pass

那么degrade是怎樣實現的呢?

def degrade(app):
    def _wrapper(function):
        def __wrapper(*args, **kwargs):
            value = None
            try:
                redis = codis_pool.get_connection()
                value = redis.get("dmonitor:degrade:%s" % app)
            except Exception, _:
                logger.info(traceback.format_exc())
            if not value or int(value) != 1:
                function()
                logger.info("[degrade] is_on: %s" % app)
            else:
                logger.info("[degrade] is_off: %s" % app)
        return __wrapper
    return _wrapper

3、任務狀態(tài)機

這個是最常用的,我們需要跟蹤落盤DB一個任務的執(zhí)行狀態(tài)(等待調度,執(zhí)行中,執(zhí)行成功,執(zhí)行失敗)

一旦do方法被@tasks_decorator裝飾,就獲得了這樣的能力。對item_param(是個json)中task_id指明的任務進行狀態(tài)管理。

@tasks_decorator
def do(item_param):
    # do whatever
    pass

tasks_decorator是怎樣實現的呢?

def tasks_decorator(function):
    def _wrap(*args, **kwargs):
        param_dict = kwargs.get('item_param')
        task_id = param_dict.get('task_id')
        try:
            param_dict.update({'status': TaskStatus.Waiting, 'start_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
            try:
                manager_dao.save_task(param_dict)
            except Exception, ex:
                pass
            _update_task_status(task_id, TaskStatus.Doing)
            function(*args, **kwargs)
            _update_task_status(task_id, TaskStatus.Done)
        except Exception as e:
            time.sleep(0.5)
            _update_task_status(task_id, TaskStatus.Fail, unicode(e.message))
            raise
    return _wrap

4、全局唯一性

在分布式+異步環(huán)境中,如果想保證exactly once是需要額外的邏輯的,其實主要是實現唯一鍵,一旦唯一鍵實現了,就可以使用公共緩存redis進行唯一鍵判定了。

do函數被unique裝飾,那么對于task_id對應的任務,全局只會執(zhí)行一次。

@unique
def do(task_id):
    # do whatever
    pass

unique是怎樣實現的呢?

def unique(function):
    def _wrap(*args, **kwargs):
        task_id = kwargs.get('task_id')
        try:
            redis = codis_pool.get_connection()
            key = "unique:%s" % task_id
            if not redis.setnx(key):
                redis.expire(key, 24*60*60)
                function(*args, **kwargs)
        except Exception as e:
            logger.error(traceback.format_exc())
            raise
    return _wrap

四、總結

AOP在少量增加代碼復雜度的前提下,顯著的獲得以下優(yōu)點:

1、使得功能邏輯和業(yè)務邏輯解耦,功能和業(yè)務的修改完全獨立,代碼結構清晰,開發(fā)方便

2、一鍵注入,代碼復用程度高,擴展方便

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • python實現批量文件重命名

    python實現批量文件重命名

    這篇文章主要介紹了python實現批量文件重命名,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • Python函數中閉包和延遲綁定詳情

    Python函數中閉包和延遲綁定詳情

    這篇文章主要介紹了Python函數中閉包和延遲綁定詳情,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • python 中pyqt5 樹節(jié)點點擊實現多窗口切換問題

    python 中pyqt5 樹節(jié)點點擊實現多窗口切換問題

    這篇文章主要介紹了python 中pyqt5 樹節(jié)點點擊實現多窗口切換問題,文中給大家介紹了python pyqt5 點擊按鈕來打開另一個窗口的方法,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒借鑒價值,需要的朋友可以參考下
    2019-07-07
  • keras獲得某一層或者某層權重的輸出實例

    keras獲得某一層或者某層權重的輸出實例

    今天小編就為大家分享一篇keras獲得某一層或者某層權重的輸出實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • 淺談django model postgres的json字段編碼問題

    淺談django model postgres的json字段編碼問題

    下面小編就為大家分享一篇淺談django model postgres的json字段編碼問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • 對Python字符串中的換行符和制表符介紹

    對Python字符串中的換行符和制表符介紹

    下面小編就為大家分享一篇對Python字符串中的換行符和制表符介紹,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • pandas apply 函數 實現多進程的示例講解

    pandas apply 函數 實現多進程的示例講解

    下面小編就為大家分享一篇pandas apply 函數 實現多進程的示例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • 對json字符串與python字符串的不同之處詳解

    對json字符串與python字符串的不同之處詳解

    今天小編就為大家分享一篇對json字符串與python字符串的不同之處詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • 淺談pytorch中torch.max和F.softmax函數的維度解釋

    淺談pytorch中torch.max和F.softmax函數的維度解釋

    這篇文章主要介紹了淺談pytorch中torch.max和F.softmax函數的維度解釋,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • python pygame實現方向鍵控制小球

    python pygame實現方向鍵控制小球

    這篇文章主要為大家詳細介紹了python pygame實現方向鍵控制小球,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05

最新評論