开源电子谱册尝试 开源电子谱册尝试
首页
  • 独奏曲
  • 重奏曲
  • Blues
  • 主题初衷与诞生
  • 介绍
  • 快速上手
  • 目录结构
  • 核心配置和约定
  • 自动生成front matter
  • Markdown 容器
  • Markdown 中使用组件
  • 相关文章

    • 使目录栏支持h2~h6标题
    • 如何让你的笔记更有表现力
    • 批量操作front matter工具
    • 部署
    • 关于写文章和H1标题
    • 关于博客搭建与管理
    • 在线编辑和新增文章的方法
  • 配置

    • 主题配置
    • 首页配置
    • front matter配置
    • 目录页配置
    • 添加摘要
    • 修改主题颜色和样式
    • 评论栏
  • 学习笔记草稿
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 独奏曲
  • 重奏曲
  • Blues
  • 主题初衷与诞生
  • 介绍
  • 快速上手
  • 目录结构
  • 核心配置和约定
  • 自动生成front matter
  • Markdown 容器
  • Markdown 中使用组件
  • 相关文章

    • 使目录栏支持h2~h6标题
    • 如何让你的笔记更有表现力
    • 批量操作front matter工具
    • 部署
    • 关于写文章和H1标题
    • 关于博客搭建与管理
    • 在线编辑和新增文章的方法
  • 配置

    • 主题配置
    • 首页配置
    • front matter配置
    • 目录页配置
    • 添加摘要
    • 修改主题颜色和样式
    • 评论栏
  • 学习笔记草稿
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Python装饰器
    • 1. 前置知识
      • 高阶函数
      • 示例1
      • 示例2
      • 闭包函数
    • 2、简单的装饰器示例
    • 3. 业务函数带参数
    • 4. 装饰器带参数
  • 好好学习天天向上
  • Python图片处理模块Pillow
  • 拓扑排序
  • C++学习笔记
  • python学习笔记
  • 天气查询邮件提醒
  • study
星一
2022-11-09
目录

Python装饰器

# python装饰器

装饰器,在不改变原函数的情况下,为其增强功能。

# 1. 前置知识

# 高阶函数

在python中函数也是被视为对象的,可以作为参数传递

# 示例1
def square(n):
    return n * n

def func(a, b, fun):
    res = fun(a) + fun(b)
    return res

print(func(2, 3, square))    # 函数square作为函数传入到函数func中

# 结果:13
# 示例2
def add(a, b):
    return a + b

def sub(a, b):
    return a - b

funcs = [add, sub]  # 函数作为列表成员方便调用
print(funcs[0](1, 2))
print(funcs[1](1, 2))

# 结果:3,-1

# 闭包函数

声明在一个函数种的函数被称为闭包函数,它可以访问其所在外部函数的参数和变量。

def outer():
    x = 5
    def inner():
        print(x)
    return inner

outer()

# 结果是 5 ,内部函数inner引用外部函数的变量   
# inner()函数就是一个闭包

# 2、简单的装饰器示例

import time

def calc_spend_time(func):
    '''
    description: 
    一个监测程序运行的装饰器函数。在不改动原业务函数的情况下,增添其功能。    
    输入一个函数,即参数为业务函数  
    返回一个函数,即新建的内部闭包函数(装饰过的函数)  
    '''
    def wrapper():
        # 调用前的操作
        start = time.time()
        # 调用业务函数   
        func()
        # 调用后的操作 
        print(f'{func} is called')
        print(func.__name__+' is called')
        print(func.__name__ + '() start')
        end = time.time()
        print('用时{:.5f}秒'.format(end-start))
    return wrapper  #返回装饰后的闭包函数   

@calc_spend_time  # 语法糖,相当于hello = decorator(hello)  

def hello():
    print('hello world!')

if __name__ == '__main__':
    hello()

# hello world!     
# <function hello at 0x01F2ED18> is called    
# hello is called
# hello() start 
# 用时0.00099秒   

# 3. 业务函数带参数


def decorator(func):
    '''
    description: 记录日志的装饰器函数。
    '''
    def wrapper(*args, **kwargs):
        '''
        业务函数的参数通过wrapper的函数来传递  
        返回值通过wrapper的返回值返回   
        '''
        value = func(*args, **kwargs)  # 记录业务函数返回值   
        
        print(f'{func} is called with arguments = {args} and kwargs = {kwargs}')
        print(f'{func} return value {value}')
        return value  # 返回业务函数的返回值  
    return wrapper

@decorator  # 语法糖,相当于hello = decorator(hello)   

def func1(*args, **kwargs):
    sum = 0
    for num in args:
        sum += num
    print(f'args = {args}, kwargs = {kwargs}')
    return sum

if __name__ == '__main__':
    func1(1, 2, c=3, d=4)

# args = (1, 2), kwargs = {'c': 3, 'd': 4}   
# <function func1 at 0x013DED18> is called with arguments = (1, 2) and kwargs = {'c': 3, 'd': 4}    
# <function func1 at 0x013DED18> return value 3   

参数*args用来发送一个非键值对的可变数量的参数列表给一个函数,可看作tuple
参数**kwargs允许你将不定长度的键值对作为参数传递给一个函数,可看作dict

# 4. 装饰器带参数


def outer(author):  # 再套一层,传入装饰器的参数   
    def middle(func):	# 中间层传入业务函数
        def wrapper(*args, **kwargs):
            value = func(*args, **kwargs)  # 记录业务函数返回值
            print('author: ', author,
                  f'\n{func} is called with arguments = {args} and kwargs = {kwargs}',
                  f'\nreturn value: {value}')
            return value   # 返回业务函数的返回值
        return wrapper
    return middle

# @outer('lei')  # 语法糖,相当于func1 = outer('lei')(func1)

def func1(*args, **kwargs):
    sum = 0
    for num in args:
        sum += num
    return sum

if __name__ == '__main__':
    func1 = outer('lei')(func1)
    func1(1, 2, c=3, d=4)
    # # 不用语法糖等价1:
    # func1 = outer('lei')(func1)
    # func1(1, 2, c=3, d=4)

    # # 不用语法糖等价2:
    # func1 = outer('lei')(func1)(1, 2, c=3, d=4)


# 输出结果:
# author:  lei
# <function func1 at 0x0192EE38> is called with arguments = (1, 2) and kwargs = {'c': 3, 'd': 4}
# return value: 3

上次更新: 2022/11/24, 22:50:32
好好学习天天向上

好好学习天天向上→

Theme by Vdoing | Copyright © 2022-2022 XingYi | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式