资讯专栏INFORMATION COLUMN

python装饰器案例

张利勇 / 3345人阅读

摘要:普通装饰器函数计算函数的运行时间黑名单过滤测试网络请求的响应时间初始装饰闭包函数判断的路径是否存在,如果不存在,则追加已取消下载此已在黑名单中获取开始请求的时间执行时间返回一个包装函数包装被装饰函数的参数列表开始

普通装饰器函数

计算函数的运行时间

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42218.html

相关文章

  • python 多个装饰的调用顺序

    摘要:如果不使用装饰器的话,普通的做法可能是在中写一堆校验代码来判断用户是否登录,然后决定后面的执行逻辑,这样比较麻烦。 前言 装饰器是程序开发中经常会用到的一个功能,也是python语言开发的基础知识,如果能够在程序中合理的使用装饰器,不仅可以提高开发效率,而且可以让写的代码看上去显的高大上^_^ 使用场景 可以用到装饰器的地方有很多,简单的举例如以下场景 引入日志 函数执行时间统计 执...

    wapeyang 评论0 收藏0
  • python:基础知识

    摘要:与字符串不同,列表元素支持改写。元组比列表更加安全,因为不能修改集合一个功能是进行集合操作,另一个功能是消除重复的元素。 基本数据类型 数字 整型,浮点型,布尔型,复数 组 序列,集合,字典 1 组 # 序列-字符串 str 不可变类型 # 序列-列表 list [1,2,3,4,5,6,as] 可变类型 # 序列-元组 tuple (1,2,3,4,5,6,as) 不可变类型 ...

    xiongzenghui 评论0 收藏0
  • Python 3.7 将引入 dataclass 装饰

    摘要:简评将于今年夏天发布,中将会有许多新东西,最激动人心的新功能之一是装饰器。因此,只需将代码更改为以下代码即可实现四种方法我们去掉了方法,以确保装饰器可以添加它生成的对应方法。 简评:Python 3.7 将于今年夏天发布,Python 3.7 中将会有许多新东西,最激动人心的新功能之一是 dataclass 装饰器。 什么是 Data Class 大多数 Python 开发人员编写过很...

    leanote 评论0 收藏0
  • python学习笔记 函数装饰

    摘要:实现一个简单的装饰器输出被装饰函数的运行时间简单运用运行结果运行过程中,首先输出装饰器函数中的内容被装饰函数运行时间长度函数名称和实际参数计算结果然后得到最终的计算结果。 函数装饰器 函数装饰器用于在源码中标记函数, 以某种方式增强函数的行为,这是一个强大的功能。 函数装饰器是一个可调用对象,其参数是另外一个函数,即被装饰函数。装饰器可能处理被装饰函数,然后将其返回,或者将其替换成另一...

    jsliang 评论0 收藏0
  • 流畅的python读书笔记-第七章-函数装饰和闭包

    摘要:函数装饰器和闭包严格来说,装饰器只是语法糖。何时执行装饰器它们在被装饰的函数定义之后立即运行。装饰器突出了被装饰的函数的作用,还便于临时禁用某个促销策略只需把装饰器注释掉。 函数装饰器和闭包 严格来说,装饰器只是语法糖。如前所示,装饰器可以像常规的可调用对象那样调用,其参数是另一个函数。有时,这样做更方便,尤其是做元编程(在运行时改变程序的行为)时。 Python何时执行装饰器 它们在...

    Hydrogen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<