欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python装饰器

程序员文章站 2022-04-24 21:28:53
python装饰器 假如你是一家视频网站的后端开发工程师,你们网站有以下几个版块: 在视频刚上线初期,为了吸引客户,你们采取了免费政策,所有视频免费观看,迅速吸引了一大批用户,免费一段时间后,发现每天巨大的带宽费用公司承受不起,所以准备对比较受欢迎的几个版块进行收费,其中包括“欧美”和“北京”专区, ......

​ 说到装饰器, 笔者刚开始学习python时是一片茫然,为什么有了函数,还需要在函数前@某个函数,后来随着学习再深入一点,觉得装饰器在python中的应用很广泛。居于此,就对装饰器加强了学习。

1、什么是装饰器:

	装饰器(Decorators)是 Python 的一个重要部分。装饰器通常是用来修改其他函数功能的函数。他们使得代码更简短,更有Python范儿。在学习python时,装饰器对于初学者来说比较难掌握的概念之一。

2、理解python函数,在python中可以将函数看作一个普通的变量当做一个参数传递给函数,甚至可以将一个函数赋值给一个变量:

	如下的例子:
def hello(name="alax"):
    return "hello " + name

print(hello())
#这个地方就是将hello()函数作为一个参数传递给print()函数
# output: 'hello alax'

# 我们甚至可以将一个函数赋值给一个变量,比如
greet = hello
# 我们这里没有在使用小括号,因为我们并不是在调用hi函数
# 而是在将它放在greet变量里头。我们尝试运行下这个

print(greet())
# output: 'hello alax'

# 如果我们删掉旧的hello函数,看看会发生什么!
del hello
print(hello())
# output: NameError

print(greet())
# output: 'hello alax'

​ 将函数作为参数传递给函数

def hello():
    return 'hello alax'

def doBeforeHello(func):
    print('在执行函数func前做的事情')
    print(func())

doBeforeHello(hello)
# output:在执行函数func前做的事情
#         hello alax

3、第一个装饰器:在充分理解了函数可以作为一个参数传递给一个函数后,我们写第一个装饰器函数。

def new_decorators(func):
    def doBeforeHello():
        print('在函数func()执行前做的事情')
        func()
        print('在函数func()执行之后做的事情')
    return doBeforeHello


def requiring_decorators():
    print('需要装饰器函数')

requiring_decorators()
# output: 需要装饰器函数

requiring_decorators = new_decorators(requiring_decorators)
requiring_decorators()
# output: 在函数func()执行前做的事情
#         需要装饰器函数
#         在函数func()执行之后做的事情

要充分的理解在装饰器装饰的函数执行前后,执行装饰器中的代码。在上述的代码中,并没有使用@符号,实现一个简单的装饰器功能的函数。上面的代码等价于下面的这段代码:

def new_decorators(func):
    def doBeforeHello():
        print('在函数func()执行前做的事情')
        func()
        print('在函数func()执行之后做的事情')
    return doBeforeHello

@new_decorators
def requiring_decorators():
    print('需要装饰器函数')

requiring_decorators()
# output: 在函数func()执行前做的事情
#         需要装饰器函数
#         在函数func()执行之后做的事情

我们在使用装饰器的时候,被装饰的函数的__name__属性变成装饰器的名字:

print(requiring_decorators.__name__)
# output: doBeforeHello

这并不是我们想要的!output输出应该是"requiring_decorators"。这里的函数被doBeforeHello替代了。它重写了我们函数的名字和注释文档(docstring)。幸运的是Python提供给我们一个简单的函数来解决这个问题,那就是functools.wraps。我们修改上一个例子来使用functools.wraps:

from functools import wraps

def new_decorators(func):
    @wraps(func)
    def doBeforeHello():
        print('在函数func()执行前做的事情')
        func()
        print('在函数func()执行之后做的事情')
    return doBeforeHello

@new_decorators
def requiring_decorators():
    print('需要装饰器函数')

print(requiring_decorators.__name__)
# output: requiring_decorators

requiring_decorators()

@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。

本文地址:https://blog.csdn.net/m0_46710786/article/details/107186416