美文网首页编程语言爱好者Python时空大数据呆鸟的Python数据分析
你知道Python装饰器怎么编写运行吗?进阶的干货来了,快准备收

你知道Python装饰器怎么编写运行吗?进阶的干货来了,快准备收

作者: Java领域指导者 | 来源:发表于2020-05-09 21:49 被阅读0次

前言

Python语言有一个比较Pythonic的功能,也是一个具有很强大功能的特性,那就是装饰器。那什么是装饰器呢?顾名思义,装饰器就是用来修饰某个函数,在不改变原来方法代码的前提下,额外的附加其他的功能和属性。可能这样说得比较抽象,下面我们通过代码实现的方式演示如何编写装饰器,以及装饰器是如何执行的。

Python装饰器的原理

Python中的装饰器是通过利用了函数特性的闭包实现的,所以我们需要了解Python闭包的原理,以及函数的功能特性。

1.1 函数特性

函数作为变量传递

def add(x):

return x+1

a = add(5)

print(a)

#运行结果:6

函数作为参数传递

def add(x):

return x+1

def execute(f):

return f(3)

print(execute(add))

#运行结果:4

函数作为返回值

def add(x):

return x+1

def execute(x):

return add(x)

print(execute(5))

#运行结果:6

函数嵌套及跨域访问

def outer():

x = 1

def inner():

print(x+1)

inner()

outer()

#运行结果:2

1.2 闭包原理

闭包其实就是在一个函数中嵌套另一个函数的定义。闭包的作用:包括了外部函数的局部变量,这些局部变量在外部函数返回后也继续存在,并能被内部函数引用。

def fun1():

x = 1

def fun2():

print(x+1)

fun2()

fun1()

#运行结果:2

编写装饰器

装饰器也可以分为两种,无参装饰器和有参装饰器

无参装饰器

"""

无参装饰器示例

AUTH:TTC

DATE:2018年6月4日 23:58:12

VERSION:v0.01

"""

from functools import wraps

# 装饰器函数

def decorator(fn):

# 这里加装饰器的意思是,当查看调用方法时,依然显示目标函数的方法名,而不是wrapper

@wraps(fn)

def wrapper(*args, **kwargs):  # 给目标函数装饰的方法

print('foo')  # 在执行目标函数之前运行

fn(*args, **kwargs)  # 执行目标函数

print('bar')  # 在目标函数之后运行

return wrapper  # 返回装饰后的函数

@decorator

def hello_decorator(name):

"""

需要装饰的函数

"""

print('hello_decorator, My name is %s' % name)

def main():

hello_decorator('TTC')

print(hello_decorator.__name__)

if __name__ == '__main__':

main()

代码执行的顺序是这样的,先进入mian()方法,执行hello_decorator()发现被decorator(fn)方法装饰hello_decorator() 该方法被当做参数传递给装饰器函数,而hello_decorator()name参数会被wrapper()接收(*args, *kwargs, 为可变参数和关键字参数, 可接受任意形式的参数),将wrapper函数会返回给主函数,从而对hello_decorator()函数添加了额外的功能,先输出foo,再执行目标函数,最后输出bar。(在这儿的重点是将函数也作为了一个参数进行传递)

[tianjun@localhost test]$ python3 example06.py

foo

hello_decorator, My name is TTC

bar

hello_decorator

这样hello_decorator()就被赋予了额外的功能,打印foo然后执行函数,执行完后再打印bar

有参装饰器

有参数的装饰器和没参数的构造器的区别在于,多了一层函数的嵌套。

"""

有参装饰器

AUTH: TTC

DATE: 2018年6月5日 17:27:35

"""

from functools import wraps

# 装饰器函数

def decorator(times):

# 外部装饰器

def out_wrapper(fn):

# 内部装饰器

@wraps(fn)

def wrapper(*args, **kwargs):

print('foo')  # 目标函数之前执行

for _ in range(times):  # 执行次数

fn(*args, **kwargs)  # 执行目标函数

print('bar')  # 目标函数之后执行

return wrapper  # 返回内部装饰器

return out_wrapper  # 返回外部装饰器

@decorator(times=3)  # 带参数的装饰器糖果语法

def hello_decorator(name):  # 被装饰函数

"""

需要修饰的函数

"""

print('hello_decorator, My name is %s' % name)

def main():

hello_decorator('TTC')

print(hello_decorator.__name__)

if __name__ == '__main__':

main()

装饰有返回值的函数

如果被装饰的函数有返回值,则需要对函数进行小小的调整。将返回的数值在变量中进行存储,然后再通过装饰器函数返回。

# 装饰器函数

def decorator(fn):

# 这里加装饰器的意思是,当查看调用方法时,依然显示目标函数的方法名,而不是wrapper

@wraps(fn)

def wrapper(*args, **kwargs):  # 给目标函数装饰的方法

print('foo')  # 在执行目标函数之前运行

result = fn(*args, **kwargs)  # 执行目标函数, 将执行结果赋值给变量

print('bar')  # 在目标函数之后运行

return result  # 返回执行的结果

return wrapper  # 返回装饰后的函数

带参数的装饰器也是同理的。

# 装饰器类

class Decorator(object):

def __init__(self, times):  # 初始化方法,传递参数

self._times = times  # 参数赋值

def __call__(self, fn):  # 魔法方法,当类被调用时执行

@wraps(fn)  # 保留原方法函数名

def wrapper(*args, **kwargs):  # 装饰器方法

print('foo')  # 在目标函数之前运行

value = None  # 声明变量

for _ in range(self._times):  # 执行多少次

value += fn(*args, **kwargs)  # 执行目标函数,将执行结果进行累加

print('bar')  # 在目标函数之后运行

return value  # 返回累加的值

return wrapper  # 返回装饰猴年的方法

装饰器的使用场景

装饰器的使用场景太多了,只要是你不想改变原来的代码,又想添加额外的功能,都可以使用装饰器来完成。

比如,我们在测试一个方法的执行时间上,就可以使用装饰器来实现。

import time

from functools import wraps

def spend_time(fn):

@wraps(fn)

def wrapper(*args, **kwargs):

start_time = time.time()  # 开始时间

result = fn(*args, **kwargs)  # 执行函数

end_time = time.time()  # 结束时间

print('执行时间:%s' % str(end_time-start_time))  # 输出花费时间

return result

return wrapper

又比如,当我们在进行数据库的操作时,有时会因为网络原因,或其他原因,导致我们的数据库操作出错,为了不让数据丢失,程序崩溃,一般会写一个装饰器来处理这样的问题。在装饰器中 对错误进行抓取,然后休息几秒再次的提交尝试,知道多次尝试依然无法完成操作再丢弃。

总之,装饰器的应用场景太多了,在这就不一一说了,总之装饰器是个很好的设计,它不仅减少了重复的代码,使代码复用性提高,而且使得代码变得更加的结构化,更容易阅读。

喜欢小编的话请多多点赞评论转发,让更多人看到获益啊~另外,小编还整理了一些Python闭包及装饰器的学习资料,有需要进阶学习的小伙伴请转发+关注小编,并加微信bjmsb1来免费领取吧~~~

还有基础教程学习资料,需要的话赶紧行动起来啦~~~

相关文章

  • 你知道Python装饰器怎么编写运行吗?进阶的干货来了,快准备收

    前言 Python语言有一个比较Pythonic的功能,也是一个具有很强大功能的特性,那就是装饰器。那什么是装饰器...

  • Python装饰器(Decorator)完全指南-进阶篇

    Decorator进阶指南 在[python装饰器完全指南基础篇中],我们已经知道了python中的装饰器本质上只...

  • Python装饰器-专题笔记

    学会装饰器,Python更进阶 函数作用域到闭包到装饰器讲解,及闭包和装饰器的运用。 [√] 慕课网Meshare...

  • 9个Python 内置装饰器: 显著优化代码

    装饰器是应用“Python 之禅”哲学的最佳 Python 特性。装饰器可以帮助您编写更少、更简单的代码来实现复杂...

  • Python中的装饰器

    本文的内容主要参考了《Python进阶》一书 装饰器(Decorators)是什么? 我理解的装饰器,主要是设计模...

  • Python进阶 装饰器

    一切皆对象 原始的装饰器 使用@的装饰器 蓝本规范 带参数的装饰器 装饰器类

  • python装饰器进阶

    为什么要使用? 使用装饰器使代码变得整洁,并且能解决硬编码问题,使用起来也很方便,但是理解起来相对没那么容易,因此...

  • Python进阶(装饰器)

    note 1:Python内置的@语法就是为了简化装饰器调用。下面两图效果一样。 note 2:python的de...

  • Python进阶 - 装饰器

    函数进阶知识 函数名只是一个指向函数的变量 在python中,一切皆对象。函数名只是一个指向函数的变量,为了验证这...

  • Python进阶-装饰器

    这篇文章要解决的问题: # 装饰器是什么? # 装饰器的种类? # 为什么使用装饰器? # 怎么使用装饰器? # ...

网友评论

    本文标题:你知道Python装饰器怎么编写运行吗?进阶的干货来了,快准备收

    本文链接:https://www.haomeiwen.com/subject/phalnhtx.html