首页 > 编程语言 >Python | 装饰器

Python | 装饰器

时间:2023-06-12 12:44:06浏览次数:42  
标签:__ return Python hello func 装饰 def

前言

其实装饰器就是类似于女孩子的发卡。你喜欢的一个女孩子,她可以有很多个发卡,而当她戴上不同的发卡,她的头顶上就是装饰了不同的发卡。但是你喜欢的女孩子还是你喜欢的女孩子。如果还觉得不理解的话,装饰器就是咱们的手机壳,你尽管套上了手机壳,但并不影响你的手机功能,可你的手机还是该可以给你玩,该打电话打电话,该玩游戏玩游戏,该收藏攻城狮白玉的博客就收藏攻城狮白玉的博客。而你的手机就变成了带手机壳的手机。

装饰器就是python的一个拦路虎,你干或者不干它,它都在那里。

要想了解装饰器,首先要了解一个概念,闭包。

闭包

什么是闭包,一句话说就是,在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了。

例子

def outer(x):
    def inner(y):
        return x + y
    return inner

print(outer(6)(5))
-----------------------------
>>>11

装饰器

接下来就讲装饰器,其实装饰器就是一个闭包,装饰器是闭包的一种应用。

什么是装饰器

简言之,python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。使用时,再需要的函数前加上@demo即可。

装饰器的使用符合了面向对象编程的开放封闭原则。

开放封闭原则主要体现在两个方面:

  1. 对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。
  2. 对修改封闭,意味着类一旦设计完成,就可以独立其工作,而不要对类进行任何修改。
def debug(func):
    def wrapper():
        print("[DEBUG]: enter {}()".format(func.__name__))
        return func()
    return wrapper

@debug
def hello():
    print("hello")

hello()
-----------------------------
>>>[DEBUG]: enter hello()
>>>hello

例子中的装饰器给函数加上一个进入函数的debug模式,不用修改原函数代码就完成了这个功能,可以说是很方便了。

带参数的装饰器

上面例子中的装饰器是不是功能太简单了,那么装饰器可以加一些参数吗,当然是可以的,另外装饰的函数当然也是可以传参数的。

def logging(level):
    def outwrapper(func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(level, func.__name__))
            return func(*args, **kwargs)
        return wrapper
    return outwrapper

@logging(level="INFO")
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[INFO]: enter hello()
>>>hello, good morning

如上,装饰器中可以传入参数,先形成一个完整的装饰器,然后再来装饰函数,当然函数如果需要传入参数也是可以的,用不定长参数符号就可以接收,例子中传入了三个参数。

类装饰器

装饰器也不一定只能用函数来写,也可以使用类装饰器,用法与函数装饰器并没有太大区别,实质是使用了类方法中的call魔法方法来实现类的直接调用。

class logging(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("[DEBUG]: enter {}()".format(self.func.__name__))
        return self.func(*args, **kwargs)

@logging
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[DEBUG]: enter hello()
>>>hello, good morning

类装饰器也是可以带参数的,如下实现

class logging(object):
    def __init__(self, level):
        self.level = level

    def __call__(self, func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(self.level, func.__name__))
            return func(*args, **kwargs)
        return wrapper

@logging(level="TEST")
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[TEST]: enter hello()
>>>hello, good morning

标签:__,return,Python,hello,func,装饰,def
From: https://www.cnblogs.com/zhangxuegold/p/17474726.html

相关文章

  • Python 有S1和S2的字符串,S2是S1的子串,输出S1中不含S2的字符串
     思路:1. 先做替换,把S1与S2相同的子串替换为空2.有坑:第一步替换后,可能会出现新的字符串有包含S1中3.利用递归再去替换1a="tomcatisabigccatatandsmallcacatt-yyds"2b="cat"34defA(a,b):5ifbnotina:#先给个递......
  • Python 集合
    Set数据类型一、创建一个set#set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。#访问速度快,天生解决了重复问题>>>s1=set(['root','gm','evescn','gm'])二、查看set>>>s1{'gm','evescn......
  • python学习笔记35-脚本有多个文件时如何指定import_path
    如果脚本涉及多个文件,且分布在多个目录中,则会涉及到import其它目录的文件.如果脚本不在脚本所在的目录run,则会涉及到run目录与脚本目录不相关.如何解决这个问题呢?假设目录结构如下:/a/b/c/bin/dfx.py/a/b/c/atpg/atpg.py/a/b/c/atpg/atpg_sim.py/a/b/c/common/my_......
  • 设计模式之装饰者模式--钢铁侠的形成
    前言本文主要讲述java常见设计模式之装饰者模式,文中使用通俗易懂的案例,使你更好的学习本章知识点并理解原理,做到有道无术。一.什么是装饰者模式装饰者模式是23种设计模式中结构型模式的一种,它的核心思想是在不必改变类文件及不使用继承的情况下,通过装饰者包裹目标对象,动态地扩......
  • Python工具箱系列(三十五)
    前文使用了SQLAlchemy的Core层来实现数据库、表与数据的CRUD。初步体现出了SQLAlchemy的优势。但ORM的特点没有充分地表现出来。下面的代码则从Python的类出现,生成表结构,并且进行数据的CRUD操作。fromsqlalchemyimport(Column,DateTime,Float,ForeignKey,Integer,MetaDa......
  • 实验6 turtle绘图与python库应用编程体验
    实验任务1task1-11fromturtleimport*2defmove(x,y):3penup()4goto(x,y)5pendown()6defdraw(n,size=100):7foriinrange(n):8fd(size)9left(360/n)10defmain():11pensize(2)12pencolor(......
  • python学习笔记33-将标准输出打印到文件中
    importsys#保存原始的stdout,方便后续恢复out_tmp=sys.stdout#将stdout重新定向到文件,这样输出的标准输出的内容就会输出到文件中sys.stdout=open('help.QWidget.rpt','w')#执行help命令,标准输出打印内容,此时会打印到文件中fromPyQt5.QtWidgetsimport......
  • python学习笔记34-获取函数的help信息
    list_for_help=list()list_for_help.append("PyQt5.QtCore")list_for_help.append("PyQt5.QtCore.QTime")list_for_help.append("PyQt5.QtGui")list_for_help.append("PyQt5.QtGui.QColor")list_for_help.append("PyQt5......
  • RC4加密算法及Python实现
    一、RC4加密算法原理RC4算法是一种流加密算法,由RonRivest在1987年设计。它的主要特点是简单快速,而且在加密解密过程中使用的密钥长度可变。因此,RC4算法被广泛应用于网络安全领域,如SSL、TLS、WEP、WPA等协议中。RC4算法的加密过程如下:初始化S盒和T数组。S盒是一个256字节的数组,用于......
  • Python工具箱系列(三十五)
    前文使用了SQLAlchemy的Core层来实现数据库、表与数据的CRUD。初步体现出了SQLAlchemy的优势。但ORM的特点没有充分地表现出来。下面的代码则从Python的类出现,生成表结构,并且进行数据的CRUD操作。fromsqlalchemyimport(Column,DateTime,Float,ForeignKey,Integer,MetaData,......