Python-装饰器Decorator

目录

1、函数装饰器-不带参数的二阶装饰器

2、函数装饰器-带参数的二阶装饰器

3、函数装饰器-不带参数的三阶装饰器

4、函数装饰器-带参数的三阶装饰器

5、类装饰器-不带参数

6、类装饰器-带参数


1、函数装饰器-不带参数的二阶装饰器

import functools


def deco(func):
    print('外部函数')

    @functools.wraps(func)
    def wrap():
        print('内部函数')
        return func()

    return wrap


@deco
def test():
    print('被装饰函数')


print(f'被装饰函数的名称={test.__name__}')
test()
D:\pycharm_workspace\Demo\venv\Scripts\python.exe D:/pycharm_workspace/Demo/demo/test.py
外部函数
被装饰函数的名称=test
内部函数
被装饰函数

Process finished with exit code 0

代码从上向下执行,当执行到 @deco的时候,会执行 test=deco(test),这时候test=wrap,所以执行结果中,会先打印出 “外部函数”,然后继续向下执行,打印出函数的名称,再继续向下执行,调用test(),相当于调用wrap(),后面的就省略不说了

2、函数装饰器-带参数的二阶装饰器

import functools


def deco(func):
    print('外部函数')

    @functools.wraps(func)
    def wrap(*args, **kwargs):
        print('内部函数')
        return func(*args, **kwargs)

    return wrap


@deco
def test(a, b, c):
    print(f'被装饰函数{a}-{b}-{c}')


print(f'被装饰函数的名称={test.__name__}')
test(1, 2, 3)
D:\pycharm_workspace\Demo\venv\Scripts\python.exe D:/pycharm_workspace/Demo/demo/test.py
外部函数
被装饰函数的名称=test
内部函数
被装饰函数1-2-3

Process finished with exit code 0

内部函数可以传形参,也可以用通用 *args和**kwargs参数

3、函数装饰器-不带参数的三阶装饰器

import functools


def demo(text):
    print('第一层')

    def deco(func):
        print('外部函数')

        @functools.wraps(func)
        def wrap(*args, **kwargs):
            print('内部函数', text)
            return func(*args, **kwargs)

        return wrap
    return deco


@demo('gg')
def test():
    print(f'被装饰函数')


print(f'被装饰函数的名称={test.__name__}')
test()
D:\pycharm_workspace\Demo\venv\Scripts\python.exe D:/pycharm_workspace/Demo/demo/test.py
第一层
外部函数
被装饰函数的名称=test
内部函数 gg
被装饰函数

Process finished with exit code 0

当代码执行到 @demo('gg'),相当于test=demo('gg')(test),所以控制台先输入 第一层,然后输出 外部函数,后面流程同之前逻辑一样

4、函数装饰器-带参数的三阶装饰器

import functools


def demo(text):
    print('第一层')

    def deco(func):
        print('外部函数')

        @functools.wraps(func)
        def wrap(*args, **kwargs):
            print('内部函数', text)
            return func(*args, **kwargs)

        return wrap
    return deco


@demo('gg')
def test(a, b):
    print(f'被装饰函数{a}-{b}')


print(f'被装饰函数的名称={test.__name__}')
test(11, 22)

就是多了传参而已

5、类装饰器-不带参数

import functools


class Demo(object):
    def __init__(self, func):
        print('初始化函数开始')
        self.func = func
        print('初始化函数结束')

    def __call__(self, *args, **kwargs):
        print('调用函数开始')
        return self.func(*args, **kwargs)


@Demo
def test():
    print(f'被装饰函数')


print('准备调用test')
test()
D:\pycharm_workspace\Demo\venv\Scripts\python.exe D:/pycharm_workspace/Demo/demo/test.py
初始化函数开始
初始化函数结束
准备调用test
调用函数开始
被装饰函数

Process finished with exit code 0

当代码执行到 @Demo,相当于 test=Demo(test),因为是类,所以执行初始化init函数,所以打印:初始化函数开始、初始化函数结束,然后继续向下执行,当调用test,相当于对实例化对象进行调用,会调用call函数,然后继续。。。

6、类装饰器-带参数

import functools


class Demo(object):
    def __init__(self, kk):
        print('初始化函数开始')
        self.kk = kk
        print('初始化函数结束')

    def __call__(self, func):
        print('调用函数开始')

        @functools.wraps(func)
        def wrap(*args, **kwargs):
            print('inner', self.kk)
            return func(*args, **kwargs)

        return wrap


@Demo('kk')
def test():
    print(f'被装饰函数')


print('准备调用test')
test()
print(test.__name__)
D:\pycharm_workspace\Demo\venv\Scripts\python.exe D:/pycharm_workspace/Demo/demo/test.py
初始化函数开始
初始化函数结束
调用函数开始
准备调用test
inner kk
被装饰函数
test

Process finished with exit code 0

当代码运行到 @Demo('kk'),相当于 test=Demo('kk')(test),所以控制打印的数据,一直到call方法里面的 调用函数开始,继续向下执行 调用test(),相当于调用call方法里面的 wrap()函数,

@functools.wraps(func)的作用是让函数名称不会变化,否则test.__name__的值是wrap
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值