Python裝飾器之一

裝飾器本質上是一個Python函數,它可讓其餘函數在不須要作任何代碼變更的前提下增長額外功能,裝飾器的返回值也是一個函數對象。它常常用於有切面需求的場景,好比:插入日誌、性能測試、事務處理、緩存、權限校驗等場景。裝飾器是解決這類問題的絕佳設計,有了裝飾器,咱們就能夠抽離出大量與函數功能自己無關的雷同代碼並繼續重用。緩存

簡單的設計了一個驗證權限的裝飾器,設計以下app

# -*- coding:utf-8 -*-

def check_is_admin(func):
    def wrapper(*args,**kwargs):
        if kwargs.get('username') != 'admin':
            raise Exception('This user is not allowed to get food')
        return func(*args,**kwargs)
    return wrapper

class Store(object):

    @check_is_admin
    def get_food(self,username,food):
        return self.get(food)

    @check_is_admin
    def put_food(self, username, food):
        return self.put(food)

    def get(self,food):
        return food

    def put(self,food):
        return food

if __name__ == '__main__':
    s = Store()
    s.get_food(**{'username':'admin1'},**{'food':'apple'})

到目前爲止,咱們的示例中老是假設裝飾器有一個名爲username的關鍵字參數傳入,可是實際狀況並不是如此,因此咱們設計了一個更智能的裝飾器,代碼以下:函數

# -*- coding:utf-8 -*-
import functools,inspect

def check_is_admin(func):
    @functools.wraps(func)

    def wrapper(*args,**kwargs):
        func_args = inspect.getcallargs(func,*args,**kwargs)

        if func_args.get('username') != 'admin':
            raise Exception('This user is not allowed to get food')
        return func(*args,**kwargs)
    return wrapper

class Store(object):

    @check_is_admin
    def get_food(self,username,food):
        return self.get(food)

    @check_is_admin
    def put_food(self, username, food):
        return self.put(food)

    def get(self,food):
        return food

    def put(self,food):
        return food

if __name__ == '__main__':
    s = Store()
    food = s.get_food(**{'username': 'admin'}, food='apple')
    print(food)

這裏咱們引入了functools,inspect模塊。inspect.getcallargs承擔了主要工做,它返回一個將參數名字和值做爲鍵值對的字典{'username':'admin','food':'apple'},這就意味着裝飾器沒必要檢查參數username是基於位置的參數仍是基於關鍵字的參數,而是隻須要在字典中查詢。性能

相關文章
相關標籤/搜索