轻松搞定python装饰器,so easy

Posted 香菜聊游戏

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了轻松搞定python装饰器,so easy相关的知识,希望对你有一定的参考价值。

学习Java的都知道Java 中有面向切面的编程,也就是aop,说白了就是在你原来的代码执行前做一些操作,这样的好处就是不修改原来的代码逻辑,增强程序的功能,很方便。人生苦短,我用python,python中也有同样的功能,而且更方便,这个功能就是装饰器

1、无参数装饰器

无参的装饰器是最简单的,万事开头难,先挑个简单的下手,不要慌,慢慢来。

def aop(func):
    print("begin----------")
    func()
    print("end-----------")

@aop
def funcMethod():
    print("run ")
    
# 执行结果    
#begin----------
#run 
#end-----------
    

可以看到语法就是在需要装饰的函数上使用@aop ,aop 表示装饰器的函数,很简单对不对。。。

2、装饰有参数的函数

有参数的函数才是开发中的常态,所以怎么实现对有参数的构造函数进行装饰

def aop(func):
    def wrap(p1):
        print("开始")
        func(p1)
        print("结束")
    return wrap

@aop
def funcMethod(p1):
    print(p1)

funcMethod("执行")

可以看到这次比第一个例子稍微复杂一些,但是也能看出装饰器的底层原理,

想要修饰一个参数的函数,为此我们在装饰器函数内部定义了一个新的函数,同样的参数,并且将函数wrap 进行了返回,也就是替换了原来的函数funcMethod

知识点:装饰器函数替换了原来的函数,将原来的函数作为新函数的一部分

3、通用的函数装饰器

通常来说我们想要实现通用装饰器,比如我们要实现一个函数的调用日志,这样每个函数的定义是不一样的,有的参数多,有的参数少,有的甚至没有参数。

def aop(func):
    def wrapper(*args, **kwargs):
        print('参数如下:')
        print(args)
        print(kwargs)
        result = func(*args, **kwargs)
        print("结束")
        return result
    return wrapper

@aop
def funcMethod(p1,p2):
    print(p1)
    print(p2)
@aop
def funcMethod2():
    print("xxxxxx")

funcMethod("执行","参数2")
funcMethod2()

注:args 形参前加’'表示可以接受多个实参值存进数组

kwargs对于在形参前加’'表示表示接受参数转化为字典类型

4、基于类的装饰器

class AopClazz(object):
    def __init__(self, f):
        self.f = f
    def __call__(self):
        print(" start")
        self.f()
        print(" end")

@AopClazz
def func():
    print("func")

func()

Python 对某个对象是否能通过装饰器( @decorator)形式使用只有一个要求:decorator 必须是一个“可被调用(callable)的对象。

对于这个 callable 对象,我们最熟悉的就是函数了。

除函数之外,类也可以是 callable 对象,只要实现了__call__ 函数(上面几个盒子已经接触过了),还有比较少人使用的偏函数也是 callable 对象。

5、内置装饰器

特性装饰器:@property

类方法装饰器: @classmethod

静态方法装饰器:@staticmethod

import math
class Circle:
    def __init__(self,radius): #圆的半径radius
        self.radius=radius

    @property
    def area(self):
        return math.pi * self.radius**2 #计算面积

    @property
    def perimeter(self):
        return 2*math.pi*self.radius #计算周长

通过@property装饰后的方法也可以像访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值;

其他的两个大家都很熟悉了,就不多介绍了

@staticmethod返回的是一个staticmethod类对象,而@classmethod返回的是一个classmethod类对象。他们都是调用的是各自的__init__()构造函数。

总结:装饰器说白了就是使用函数替换当前的实现,没有太多秘密

以上是关于轻松搞定python装饰器,so easy的主要内容,如果未能解决你的问题,请参考以下文章

12步轻松搞定python装饰器

python使用上下文对代码片段进行计时,非装饰器

装饰器

Spring Boot 日志脱敏,3 步搞定!So easy~!

Spring Boot 日志脱敏,3 步搞定!So easy~!

轻松理解python中的闭包和装饰器 (下)