Python学习—装饰器的力量 (一)

简介: Python学习—装饰器的力量 (一)

Python学习—装饰器的力量
作为许多语言都存在的高级语法之一,装饰器是你必须掌握的知识点。

Python的装饰器(Decorator)允许你扩展和修改可调用对象(函数、方法和类)的行为,而无需永久修改可调用的对象本身。进一步解释就是装饰器(Decorator):从字面上理解,就是装饰对象的器件。可以在不修改原有代码的情况下,为被装饰的对象增加新的功能或者附加限制条件或者帮助输出。装饰器有很多种,有函数的装饰器,也有类的装饰器。装饰器在很多语言中的名字也不尽相同,它体现的是设计模式中的装饰模式,强调的是开放封闭原则。装饰器的语法是将@装饰器名,放在被装饰对象上面。

@dec
def func():    
    pass

在进行装饰器的介绍之前,我们必须先明确几个概念和原则:
首先,Python程序是从上往下顺序执行的,而且碰到函数的定义代码块是不会立即执行的,只有等到该函数被调用时,才会执行其内部的代码块。

def foo():    
    print("foo函数被运行了!")
#如果就这么样,foo里的语句是不会被执行的。
#程序只是简单的将定义代码块读入内存中。
# foo()    只有调用了,才会执行

其次,由于顺序执行的原因,如果你真的对同一个函数定义了两次,那么,后面的定义会覆盖前面的定义。因此,在Python中代码的放置位置是有区别的,不能随意摆放,通常函数体要放在调用的语句之前。

def foo():    
    print("我是上面的函数定义!")

foo()

def foo():    
    print("我是下面的函数定义!")

foo()
#----------------
#执行结果:
我是上面的函数定义!
我是下面的函数定义!

然后,我们还要先搞清楚几样东西:函数名、函数体、返回值,函数的内存地址、函数名加括号、函数名被当作参数、函数名加括号被当作参数、返回函数名、返回函数名加括号。

def outer(func):    
    def inner():        
        print("我是内层函数!")    
    return inner

def foo():    
    print("我是原始函数!")

outer(foo)
outer(foo())

运行结果如下:

D:\anaconda3\python.exe D:/pythonProject/明日科技网络爬虫/aiohttp复现.py
我是原始函数!

Process finished with exit code 0

函数名:foo、outer、inner
函数体:函数的整个代码结构
返回值:return后面的表达式
函数的内存地址:id(foo)、id(outer)等等
函数名加括号:对函数进行调用,比如foo()、outer(foo)
函数名作为参数:outer(foo)中的foo本身是个函数,但作为参数被传递给了outer函数
函数名加括号被当做参数:其实就是先调用函数,再将它的返回值当做别的函数的参数,例如outer(foo())
返回函数名:return inner
返回函数名加括号:return inner(),其实就是先执行inner函数,再将其返回值作为别的函数的返回值。
如果你能理解函数也是一个对象,就能很容易地理解上面的概念。

有了这些基本的概念,我们就可以通过一个实例来讲解Python中装饰器的作用了。

下例是针对函数的装饰器。
虚拟场景
有一个大公司,下属的基础平台部负责内部应用程序及API的开发。另外还有上百个业务部门负责不同的业务,这些业务部门各自调用基础平台部提供的不同函数,也就是API处理自己的业务,情况如下:

# 基础平台部门开发了上百个函数API
def f1():    
    print("业务部门1的数据接口......")
def f2():    
    print("业务部门2的数据接口......")
def f3():    
    print("业务部门3的数据接口......")
def f100():    
    print("业务部门100的数据接口......")
#各部门分别调用自己需要的API
f1()
f2()
f3()
f100()

运行结果如下:

D:\anaconda3\python.exe D:/pythonProject/明日科技网络爬虫/aiohttp复现.py
业务部门1的数据接口......
业务部门2的数据接口......
业务部门3的数据接口......
业务部门100的数据接口......

Process finished with exit code 0

公司还在创业初期时,基础平台部就开发了这些函数。由于各种原因,比如时间紧,比如人手不足,比如架构缺陷,比如考虑不周等等,没有为函数的调用进行安全认证。现在,公司发展壮大了,不能再像初创时期的“草台班子”一样将就下去了,基础平台部主管决定弥补这个缺陷,于是(纯属虚构场景):

第一天:主管叫来了一个运维工程师,工程师跑上跑下逐个部门进行通知,让他们在代码里加上认证功能,然后,当天他被开除了。

第二天:主管又叫来了一个运维工程师,工程师用shell写了个复杂的脚本,勉强实现了功能。但他很快就回去接着做运维了,不会开发的运维不是好运维…

第三天:主管叫来了一个python自动化开发工程师。哥们是这么干的,只对基础平台的代码进行重构,让N个业务部门无需做任何修改。这哥们很快也被开了,连运维也没得做。

def f1():    
    #加入认证程序代码    
    print("业务部门1数据接口......")
def f2():   
    # 加入认证程序代码    
    print("业务部门2数据接口......")
def f3():    
    # 加入认证程序代码    
    print("业务部门3数据接口......")
def f100():    #
    加入认证程序代码    
    print("业务部门100数据接口......")
#各部门分别调用
f1()
f2()
f3()
f100()

第四天:主管又换了个开发工程师。他是这么干的:定义个认证函数,在原来其他的函数中调用它,代码如下。

def login():    
    print("认证成功!")
def f1():    
    login()    
    print("业务部门1数据接口......")
def f2():    
    login()    
    print("业务部门2数据接口......")
def f3():    
    login()    
    print("业务部门3数据接口......")
def f100():    
    login()    
    print("业务部门100数据接口......")
#各部门分别调用
f1()
f2()
f3()
f100()

但是主管依然不满意,不过这一次他解释了为什么。主管说:写代码要遵循开放封闭原则,简单来说,已经实现的功能代码内部不允许被修改,但外部可以被扩展。如果将开放封闭原则应用在上面的需求中,那么就是不允许在函数f1 、f2、f3…f100的内部进行代码修改,但是可以在外部对它们进行扩展。

第五天:已经没有时间让主管找别人来干这活了,他决定亲自上阵,使用装饰器完成这一任务,并且打算在函数执行后再增加个日志功能。主管的代码如下:

def outer(func):    
    def inner():        
        print("认证成功!")        
        result = func()        
        print("日志添加成功")        
        return result   
    return inner
@outerdef 
f1():    
    print("业务部门1数据接口......")
@outerdef 
f2():    
    print("业务部门2数据接口......")

@outer
def f3():    
    print("业务部门3数据接口......")
@outer
def f100():    
    print("业务部门100数据接口......")
#各部门分别调用
f1()
f2()
f3()
af100()

使用装饰器@outer,也是仅需对基础平台的代码进行拓展,就可以实现在其他部门调用函数API之前都进行认证操作,在操作结束后保存日志,并且其他业务部门无需对他们自己的代码做任何修改,调用方式也不用变。
接下文 Python学习—装饰器的力量 (二)https://developer.aliyun.com/article/1618949

相关文章
|
4天前
|
缓存 开发者 Python
探索Python中的装饰器:从入门到实践
【9月更文挑战第36天】装饰器,在Python中是一种特殊的语法糖,它允许你在不修改原有函数代码的情况下,增加额外的功能。本文将通过浅显易懂的语言和实际代码示例,带你了解装饰器的基本原理,探索其背后的魔法,并展示如何在实际项目中运用这一强大工具。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往更高效、更优雅代码的大门。
25 11
|
5天前
|
缓存 Python
Python编程中的装饰器深度探索
本文深入探讨了Python中装饰器的高级用法,从基本定义到实际应用,展示了如何利用装饰器提升代码的灵活性和可维护性。通过具体示例,解析了装饰器在函数增强、日志记录、权限验证等方面的应用,旨在帮助读者彻底理解和掌握这一强大的编程工具。
|
4天前
|
测试技术 开发者 Python
深入浅出Python装饰器
【9月更文挑战第36天】本文将通过浅显易懂的语言和实际代码示例,带领读者深入理解Python中一个强大而神秘的功能——装饰器。我们将从装饰器的基础概念讲起,逐步深入到它们的高级应用,最后探讨如何在实际项目中运用装饰器来简化代码和增强程序的可维护性。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往高效编程的大门。
|
2天前
|
缓存 测试技术 开发者
探索Python中的装饰器:提升代码的灵活性和可维护性
在Python编程中,装饰器是一种强大且灵活的工具,它允许开发者在不修改现有代码的基础上,为函数或类添加额外的功能。本文将深入探讨装饰器的定义、使用场景以及如何创建自定义装饰器。通过实用的示例,我们将展示如何利用装饰器来增强代码的可重用性和可读性。
|
2天前
|
数据采集 数据挖掘 大数据
【Python篇】详细学习 pandas 和 xlrd:从零开始
【Python篇】详细学习 pandas 和 xlrd:从零开始
15 2
|
3天前
|
缓存 数据安全/隐私保护 开发者
探索Python中的装饰器:提升代码效率与可读性
在本文中,我们将深入探讨Python中的装饰器——一种能够修改或增强函数行为的强大工具。通过详细讲解装饰器的定义、使用方法以及实际案例分析,我们希望能够帮助读者更好地理解和应用这一技术,从而编写出更加高效和易读的代码。无论是初学者还是经验丰富的开发者,都能从本文中获得有价值的见解和技巧。
|
4天前
|
测试技术 数据安全/隐私保护 开发者
探索Python中的装饰器:从基础到进阶
【9月更文挑战第36天】本文旨在通过深入浅出的方式,引导读者理解Python装饰器的基本概念和实际应用。文章不仅涵盖装饰器的定义、工作原理和基本用法,还将探讨高级应用,如带参数的装饰器和装饰器栈。适合初学者和有一定经验的开发者阅读,以拓展对Python语言特性的理解和应用。
|
4天前
|
设计模式 监控 Python
探索Python中的装饰器及其应用
本文旨在深入探讨Python中一个非常强大且灵活的特性——装饰器(Decorators)。装饰器允许我们修改或扩展一个函数或方法的行为,而无需永久性地修改其代码。这一特性在实现代码复用、日志记录、权限验证等方面表现出了极大的灵活性和便利性。文章首先介绍装饰器的基本概念和定义方式,然后通过具体的代码示例展示如何使用装饰器来增强现有函数的功能。最后,讨论装饰器的高级应用,包括带参数的装饰器、多层装饰以及与类方法的结合使用等,帮助读者全面理解并有效利用这一工具。
|
4天前
|
设计模式 开发框架 测试技术
探索Python编程中的装饰器
【9月更文挑战第36天】在Python的世界里,装饰器是一个既神秘又强大的工具。它们不仅能够增强函数的功能,还能让代码更加简洁和模块化。本文将通过实例介绍装饰器的基本概念、使用方法以及如何自定义装饰器,旨在帮助读者掌握这一实用技术,从而提升代码的可读性和复用性。
|
4天前
|
设计模式 缓存 测试技术
探索Python中的装饰器:提升代码效率与可读性
本文深入探讨Python装饰器的概念、使用方法和实际应用场景。通过详细讲解和示例,读者将学会如何利用装饰器简化代码、增强功能模块的可重用性,并提高开发效率。无论是初学者还是经验丰富的开发者,都能从中获得有价值的见解和实用的编程技巧。
12 1