計算函數的運行時間網絡
import requests import time import re # 黑名單 filter_urls = ['www.hao123.com', 'www.baidu.com', 'www.jd.com'] def filter_url(url): # 過濾url print(url) host = re.findall(r'http[s]?://(.*?)/', url)[0] return host in filter_urls # 測試網絡請求的響應時間 def check_runtime(func): print('--初始裝飾--', func.__name__) def wrapper(url, *args, **kwargs): # 閉包函數 # 判斷url的 / path路徑是否存在,若是不存在,則追加/ if url[7:].find('/') == -1 or url[8:].find('/') == -1: url += '/' if filter_url(url): print('---已取消下載--:此url已在黑名單中') return # 獲取開始請求的時間 start_time = time.time() # result = func(*args, **kwargs) result = func(url, *args, **kwargs) delta_seconds = round(time.time() - start_time, 5) print('[執行時間%.5f]' % delta_seconds) return result return wrapper # 返回一個包裝函數(包裝被裝飾函數的參數列表) @check_runtime def request(url): print('--開始請求--', url) resp = requests.get(url) print('--響應--', resp.status_code) print(resp.content) print('---完成請求---') request('http://www.hao123.com')
帶參數裝飾器
設定權限(表) 8 查詢(QUERY) 4 增長(ADD) 2 刪除(DELETE) 1 修改(UPDATE) 0 無(NOSET)
設定角色——權限 admin 15(8421) | default, 8
設置用戶-角色 disen: admin | cici: defaultsession
假如當前session中登陸的用戶是cici,其權限值爲8閉包
import time current_rights = 8 # 當前登陸用戶的權限值 PERMISSION = (('QUERY', 8), ('ADD', 4), ('DELETE', 2), ('UPDATE', 1), ('NOSET', 0)) def get_permission(permission): # 根據權限名,返回權限值 for item in PERMISSION: if permission in item: return item[1] def check_permission(permission): print('--驗證權限--', permission) def wrapper1(func): print('--初始化裝飾函數--') def wrapper2(*args, **kwargs): # 檢查當前用戶的權限 permission_value = get_permission(permission) # print(permission_value) if current_rights & permission_value != permission_value: print('當前用戶沒有權限') return result = func(*args, **kwargs) return result return wrapper2 return wrapper1 @check_permission('DELETE') def delete_order(id): print('當前用戶 cici 正在刪除訂單:', id) time.sleep(2) print('刪除成功!') def add_permission(permission): # 添加權限 global current_rights current_rights |= get_permission(permission) # add_permission('DELETE') delete_order(1010111)
class Check(): def __init__(self, func): self.func = func def __call__(self, *args): self.func(*args) @Check def login(uid): print(uid)
被裝飾的方法會傳遞給裝飾器的構造器(__init__),而後在被裝飾的函數被調用的時候,裝飾器的__call__()方法就會執行
注意: 在裝飾階段,__init__ 函數執行,在被裝飾的方法被調用的時候,__call__ 執行
class Check(): def __init__(self, name): self.name = name def __call__(self, func): def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper @Check('log') def login(uid): print(uid)
__call__()會在裝飾階段被調用
import time import requests RETRY_TIME = 3 DOWNLOAD_DELAY = 2 class Retry(object): def __init__(self,retries = 3,delay=0): self.retries = retries self.delay=delay def __call__(self,func): def wrapper(*args, **kwargs): for i in range(self.retries): try: result=func(*args,**kwargs) except Exception as e: print(e) time.sleep(self.delay) continue else: return result return wrapper @Retry(RETRY_TIME,DOWNLOAD_DELAY) def fetch(url): print(f'Start fetch {url}') resp = requests.get(url,timeout=5) print(resp.status_code) fetch('http://www.baidu.com')