Python笔记之装饰器

什么是装饰器

Python中的装饰器是一个特殊的函数,它用来修饰我们定义的普通函数,使其在调用前后增加额外功能而不需要修改原代码。装饰器的本质目的是美化精简代码,当然这种操作能让代码维护起来更方便。
实质:是一个函数
参数:是需要修饰的函数名(Python中一切皆对象,函数也可以作为参数 传递。函数名非函数调用)
返回:是修饰完的函数名(非函数调用)
作用:为已经定义的函数增加额外功能
特点:不需要被修饰的函数做代码上的修改
它的应用场景多在插入日志、性能测试、事务处理、权限校验等。

前言

Python中函数内可以再定义函数
举个例子:

def outside():
    def inside():
        print("*********")
    inside()


outside()

这里需要注意的是,内部函数inside只能在外部函数outside里被调用,在其外是不能被调用的。

Python中一切皆对象,函数本身也可以作为参数传递
举个例子:

def outside(function):
    def inside():
        print("*********")
        function()
    inside()


def say_hello():
    print("hello")


outside(say_hello)

这里需要注意的是,当把函数作为参数传递的时候,一定是传递的函数名,即say_hello而不是say_hello()。加了括号表示函数调用,即函数会立即执行一次。

从函数中返回一个函数
举个例子:

def outside(function):
    def inside():
        print("*********")
        return function
    return inside


def say_hello():
    print("hello")


outside(say_hello)()()

这里outside函数内部两个return返回的是函数名即没有加“()”。最后一行函数调用代码,第一个括弧表示传参并执行outside函数,第二个括弧表示调用outside函数返回的inside函数,第三个括弧表示调用inside函数返回的function即我们的参数say_hello函数。

进入正题

模拟一个场景。我们做了一个项目,里面有很多定义的函数,为了后期好维护,现在的需求是要给每个函数打log,在函数被调用的时候输出一行字记录函数调用情况。之前也许我们会这么写代码:

def say_hello():
    print("hello")
    # 记录调用情况
    print("say_hello函数被调用")


def say_happy():
    print("happy")
    # 记录调用情况
    print("say_happy函数被调用")

这样可以达到目的,不过显得有点呆,代码工作量很大。而且三条记录调用情况的代码看起来差不多,很重复,如果有办法能获取到函数名字的话,包装成一个函数调用可能相对好一些。
基于我们前言讲的东西,可以改进我们的代码。

def log(function):
    def wrap():
        print("{}函数被调用".format(function.__name__))
        return function()
    return wrap


def say_hello():
    print("hello")


def say_happy():
    print("happy")


'''
下面代码等价于先接收返回值wrap函数名,在加上()调用这个函数
x = log(say_hello)
x()

'''
log(say_hello)() 
log(say_happy)()

我们写的这个log函数其实就是一个装饰器。用@的方式表现出来是这样子的:

def log(function):
    def wrap():
        print("{}函数被调用".format(function.__name__))
        return function()
    return wrap


@log
def say_hello():
    print("hello")


@log
def say_happy():
    print("happy")


say_hello()
say_happy()

log函数里面的代码可能有些小伙伴会有疑虑说return wrap去调用感觉很重复。能不能删掉第2行和第5行代码,只在log函数里面写print和return function()两行代码。不可以,程序会报错!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值