轻松搞定python装饰器,so easy

举报
香菜聊游戏 发表于 2021/09/26 11:07:40 2021/09/26
【摘要】 轻松搞定python装饰器

学习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__()构造函数。

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

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。