装饰器与偏函数(PY高级编程系列)

装饰器

在定义类时候, 使用静态方法 @staticmethod, 类方法 @classmethod 上面的 @就是装饰器之一

引入装饰器

不想做饭和洗碗

def eat():
    print('我正在吃饭')


def a1(b1):  # b1是函数
    def c1():
        print('把饭做好了')
        b1()
        print('把碗洗好')
    
    return c1


d1 = a1(eat)  # 传入函数
d1()

06.装饰器-001图

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值

也是一个函数对象

它经常用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景

使用与定义装饰器

# 这个函数并没有发生变化 只是需要把顺序往上调整
def a1(b1):  # b1是传入参数, 这个参数作为函数传入, 表示额外功能 | a1 就是装饰器 (高阶函数)
    def c1():
        print('把饭做好了')
        b1()
        print('把碗洗好')
    
    return c1

# 这个函数需要在头加上 引用装饰器
@a1  # a1 引用装饰器
def eat():
    print('我正在吃饭')

# 调用直接使用 主要的函数即可 无需再调用 a1, 并传入值
# 使用装饰器
eat()
print(eat.__name__)  # c1

06.装饰器-002图

但打印 eat的名字时, 返回的却不是其本身 eat 而是装饰器名字

优化, 使其 打印eat的名字时, 返回的也是eat

# 导入包装
from functools import wraps

# 在装饰器函数下进行处理 使用  @wraps(函数)
def a1(b1):  # b1是传入参数, 这个参数作为函数传入, 表示额外功能 | a1 就是装饰器 (高阶函数)
    @wraps(b1)
    def c1():
        print('把饭做好了')
        b1()
        print('把碗洗好')
    
    return c1

06.装饰器-003图

练习 工作与日志

import time
print('-' * 80)


# 记录日志专用
def loger(func):
    @wraps(func)
    def a2():
        print('日志时间', time.time())
        func()
        
    return a2


@loger
def work():
    print('我在工作')

    
work()
print(work.__name__)

06.装饰器-004图

装饰器给定参数

# 记录日志专用2
# 装饰器需要通用 可能需要 日志类型(级别) 日志保存位置
# 先给予工作的注入参数

def loger2(func):
    @wraps(func)
    def a2(*args, **kwargs):
        print('日志时间', time.time())
        func(*args, **kwargs)
    
    return a2


@loger2
def work2(name):  # 当前 work具有参数, 可能多个
    print(f'{name}在工作')


work2('小明')
print(work2.__name__)

06.装饰器-005图

# 在上一层加嵌套函数
def b2(filePath='06.log'):
    def loger2(func):
        @wraps(func)
        def a2(*args, **kwargs):
            print('日志时间', time.strftime('%H:%M:%S', time.localtime()), file=open(filePath, 'a', encoding='utf-8'))
            func(*args, **kwargs)
        
        return a2
    
    return loger2


@b2('06-work2.log')
def work2(name1, name2):  # 当前 work具有参数, 可能多个
    print(f'{name1}{name2}在工作')


work2('小明', '小花')
print(work2.__name__)

06.装饰器-006图
06.装饰器-007图

使用类进行做装饰器

# 使用类做装饰器
class Logs:
    def __init__(self, logLevel='info', filePath='06.class-logs.log'):
        self.logLevel = logLevel
        self.filePath = filePath
    
    def __call__(self, func):  # 定义装饰器
        @wraps(func)
        def a2(*args, **kwargs):
            f = open(self.filePath, 'a', encoding='utf-8')
            print(f'[{self.logLevel}] 日志时间', time.strftime('%H:%M:%S', time.localtime()), file=f)
            func(*args, **kwargs)
        
        return a2


# 使用类做装饰器
@Logs(logLevel='info', filePath='06.class-logs.log')
def work3(name1, name2):  # 当前 work具有参数, 可能多个
    print(f'{name1}{name2}在工作')


work3('张三', '李四')
print(work3.__name__)

06.装饰器-008图

偏函数

Python的functools 模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。要注意,这里的
偏函数和数学意义上的偏函数不一样。
如 int

# 偏函数
from functools import partial
a4 = int('13', 16)
print(a4, type(a4))  # 16进制数字字符串转为 10进制数字 | 19
b4 = int('13', 8)
print(b4, type(b4))  # 8进制数字字符串转为 10进制数字
c4 = int('1001', 2)
print(c4, type(c4))  # 2进制数字字符串转为 10进制数字

# 如果每一次都需要进行转可能不方便
bin_to_dec = lambda _: int(_, 2)

print(bin_to_dec('1001'))

# 可以使用这样方式 偏函数  是这个好还是lambda 把一些函数的参数进行固定, 可以使一些函数的参数进行固定
bin_to_dec = partial(int, base=2)

print(bin_to_dec('1001'))

06.装饰器-009图

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CY3761

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值