测开之函数进阶篇・第七篇《装饰器》

Posted 七月的小尾巴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了测开之函数进阶篇・第七篇《装饰器》相关的知识,希望对你有一定的参考价值。

装饰器

开放封闭原则

软件实体应该是可扩展、而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。

装饰器的作用

在不更改原功能函数内部代码,并且不改变调用方法的情况下为原函数添加新的功能。

装饰器的应用场景

  1. 登录验证
  2. 函数运行时间统计
  3. 执行函数之前做准备工作
  4. 执行函数后的清理工作

实现一个装饰器

”“”
需求:在访问网站前,我们需要判断用户登录
在不更改原功能的基础上,新增新的功能
“”“
def login(func):

    def fun():
	    username = "python"
		password = '123456'
        user = input("请输入账号:")
        pwd = input("请输入密码:")

        if username == user and pwd == password:
            func()

        else:
            print("账号或者密码错误")

    return fun


@login
def index():
    print('这个是网站的首页')


index()

装饰器原理阐述

将装饰的函数当做一个参数传到装饰器中,并且让被装饰的函数名执行装饰器内部的函数,在装饰器内部函数中用接收到的参数在调用被装饰的函数。

带参数的装饰器

def login(func):
    def fun(*args, **kwargs):
        print("装饰器功能代码:登录")
        func(*args, **kwargs)

    return fun


@login
def index():
    print("这个是网站首页")

@login
def good_list(num):
    print("这里是网站列表第{}页".format(num))


index()
good_list(10)

装饰器装饰类

首先,我们在装饰类之前,我们先定义一个普通的类,并且打印这个类信息,先来查看一下。


class MyClass:
    def __init__(self):
        pass


m = MyClass()
print(m)

返回:<__main__.MyClass instance at 0x109137560>

我们可以看到该类的内存地址。那么下面我们定一个装饰器装饰类,我们依旧用之前的login装饰器。我们来看一下打印信息。

def login(func):
    def fun(*args, **kwargs):
        print("装饰器功能代码:登录")
        func(*args, **kwargs)

    return fun


@login
class MyClass:
    def __init__(self):
        pass


m = MyClass()
print(m)

返回:None

装饰器装饰类的时候,和装饰函数的时候有所不同。从上方代码中,我们可以看到,由原先的对象信息变成返回None了。那么是什么原理呢?

首先,我们在使用 @login 装饰器时,相当于执行了 Myclass = login(MyClass),那么原先装饰器是针对函数使用的,现在我们将类给传过去的时候,相当于直接执行了 fun() 的函数,但是我们可以看到, fun() 函数内部中并没有 rentun ,因此返回了None,此时我们在函数中加上return。

def login(func):
    def fun(*args, **kwargs):
        print("装饰器功能代码:登录")
        return func(*args, **kwargs)
        

    return fun


@login
class MyClass:
    def __init__(self):
        pass


m = MyClass()
print(m)

返回:<__main__.MyClass instance at 0x10be32560>

因此,在装饰类的时候,必须加上return,如果是装饰函数的话,不一定需要加上return。

定义一个时间装饰器

import time


def wapper(func):

    def count_time(*args, **kwargs):

        start_time = time.time()
        func(*args, **kwargs)

        end_time = time.time()
        print("函数运行的时间为:{:.5f}".format(end_time - start_time))

    return count_time()

以上是关于测开之函数进阶篇・第七篇《装饰器》的主要内容,如果未能解决你的问题,请参考以下文章

测开之数据类型进阶篇・第四篇《生成器和迭代器》

测开之函数进阶篇・第五篇《递归函数纯函数匿名函数偏函数》

测开之数据类型进阶篇・第三篇《推导式》

测开之面向对象进阶篇・《多态》

测开之面向对象进阶篇・《属性自省》

测开之面向对象进阶篇・《魔术方法》