装饰器是什么东西?为什么很多人一个月还学不会?

3 篇文章 0 订阅
1 篇文章 0 订阅

一文读懂装饰器

您是否有这样的烦恼?

研究很长时间装饰器了但是还不明白装饰器是什么东西?
明明上次感觉有点眉目了,但是感觉没内味。
今天希望通过这篇文章能让您知道装饰器到底是什么?

在这之前您需要了解闭包(在这里我就不多赘述,大家自行百度)

装饰器能干什么?

装饰器模式(Decorator
Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

简单一点说就是在原有函数基础上添加方法,让被装饰的函数运行装饰函数的代码。

这里有一个例子:

import time
# 是否为质数
def is_prime(num):
    if num < 2:
        return False
    elif num == 2:
        return True
    else:
        for i in range(2, num):
            if num % i == 0:
                return False
        return True

# 计算时间
def prime_nums():
    t1 = time.time()
    for i in range(2, 10000):
        if is_prime(i):
            print(i)
    t2 = time.time()
    print(t2 - t1)

prime_nums()

从上面代码可以看出prime_nums既有逻辑的部分(打印质数),也有计算时间的部分所以可以看出代码可读性非常的低,想要变这样的问题需要用到装饰器。

这段代码等同于将计时与操作分开写,之后利用装饰器的特性将两段代码结合起来
import time


# func等同于我等一下要运行这个函数
def diaplay_time(func):
    # 该函数表示要运行哪些内容
    def wrapper():
        t1 = time.time()
        # 这里表示运行函数-->装饰谁就运行谁
        func()
        t2 = time.time()
        print(t2 - t1)
    return wrapper


def is_prime(num):
    if num < 2:
        return False
    elif num == 2:
        return True
    else:
        for i in range(2, num):
            if num % i == 0:
                return False
        return True

# 装饰这段代码也就意味着func=prime_nums()
@diaplay_time
def prime_nums():
    for i in range(2, 10000):
        if is_prime(i):
            print(i)


prime_nums()

这样您就学会了装饰器的基础操作了,但是我们需要参数应该怎么办?

import time

# func等同于我等一下要运行这个函数
def diaplay_time(func):
    # 该函数表示要运行哪些内容(如果装饰的函数需要参数需要在函数内写入参数)
    def wrapper(*args):
        t1 = time.time()
        # 这里表示运行函数-->装饰谁就运行谁 (这里也需要将参数放进去)
        result = func(*args)
        t2 = time.time()
        print(t2 - t1)
        # 如果装饰的函数有返回值,那么这里也需要进行返回
        return result
    return wrapper


def is_prime(num):
    if num < 2:
        return False
    elif num == 2:
        return True
    else:
        for i in range(2, num):
            if num % i == 0:
                return False
        return True

@diaplay_time
# 这里需要传入参数需要在上面进行一些定义
def count_prime_nums(max_num):
    count = 0
    for i in range(2, max_num):
        if is_prime(i):
            count += 1
    return count

# 这里写入需要传的参数  参数传递过程: 10000-->*args-->func(*args)-->count_prime_nums(max_num)
nums = count_prime_nums(10000)
print(nums)

这样的操作也可以运用到Django的验证用户是否登录的装饰器(虽然上下文能解决,但是有的面试官还是要问)

这个就不做过多的解释了
def check_login(func):  # 自定义登录验证装饰器
    def warpper(request, *args, **kwargs):
        is_login = request.session.get('is_login', False)
        if is_login:
            func(request, *args, **kwargs)
        else:
            return redirect("/login")
    return warpper

这就是装饰器了
另外附上学习的地址:
https://www.bilibili.com/video/av25698102

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值