普通装饰器函数
计算函数的运行时间
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: default
假如当前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')