8

普通装饰器函数

计算函数的运行时间

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')

rottengeek
476 声望78 粉丝

后续python相关内容移步简书与知乎(python进阶,爬虫,数据分析,机器学习,自然语言处理,知识图谱)