Python装饰器

装饰器推导

复制代码
"""
    装饰器(decorator):
        理解这个知识点的精髓
    思考:
        1.问题:模拟完成用户的增删改功能

        2.问题:在操作用户时添加日志功能,日志代码过多,会造成代码冗余
            解决: 抽取日志函数,在功能性函数中调用即可

        3.问题:log()代码需要修改的功能性代码过多,个人工作量大
            解决: 以功能性函数作为参数,在日志内部执行功能性函数,对其增强

        4.问题:调用功能性代码发生变化,调用者也会发生变化,考虑能不能不改变原有代码对其增加日志考虑
            解决:使用返回值为函数,对函数进行增强,给当前log函数一个函数参数,返回一个
            新的增强之后的函数,并将返回后的函数命名为原功能性函数

    1.什么是装饰器?
        就是一个函数
        作用:在不改变原有代码的情况下,对函数本身进行增强

    2.装饰器语法糖    --sweet
        @ + 装饰器函数名称
"""

推导过程

python 复制代码
#装饰器:本质就是一个函数
def log(func):
    def wrapper():
        print("log.......before....")
        func()
        print("log.......after....")
    return wrapper

@log
def add_user():
    print("add user ......")
@log
def del_user():
     print("del user ......")
@log
def upd_user():
     print("upd user ......")


#add_user = log(add_user)
print("---增加---")
add_user()
print("---删除---")
del_user()
print("---更改---")
upd_user()

# del_user()
# upd_user()

函数装饰器

复制代码
"""
    函数装饰器
        1.装饰器传递
            建议在装饰器参数传递的过程中使用参数的通用
                *args,**kwargs
        2.无参装饰器
        3.有参装饰器

有参装饰器与无参装饰器的区别

python 复制代码
#1.无参装饰器
# def log(func):
#     def wrapper(*args, **kwargs):
#         print("log......")
#         func(*args,**kwargs)
#     return wrapper

#2.有参装饰器
def log(user,time):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"log......{user}.....{time}")
            func(*args,**kwargs)
        return wrapper
    return decorator

import time
user = "lisi"
time = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())

@log(user,time)
def add_user(username,password):
    print(f"add....{username}......{password}")



add_user("zhangsan","123456")

无参装饰器练习

python 复制代码
#让传入的值自加100
def add_number(func):
    def wrapper(*args,**kwargs):
        result = func(*args,**kwargs)
        new_result = result + 100
        return new_result       #result + 100
    return wrapper

@add_number
def print_number(number):
    return  int(number)

print(print_number(666))

类装饰器

复制代码
"""
    类装饰器    --魔术方法  __call__()  专门在类中定义装饰器
        1.无参类装饰器

        2.有参类装饰器

        3.装饰器的顺序问题
            离原函数越近的的装饰器,先增强
"""

有参装饰器与无参装饰器的区别

python 复制代码
#1.无参类装饰器
class log():
    #通过构造方法传递原函数对象
    def __init__(self,func):
        self.func = func
    #通过call实现装饰器函数
    def __call__(self,*args,**kwargs):
        print("log......")      #增强的代码
        self.func(*args,**kwargs)

#2.有参类装饰器
class args_log():
    #通过构造方法传递装饰器的参数
    def __init__(self,user,time):
        self.user = user
        self.time = time
    #通过call方法传递原函数对象
    def __call__(self,func):
        def wrapper(*args,**kwargs):
            print(f"log......{self.user}...{self.time}")
            func(*args,**kwargs)
        return wrapper

import time
user = "lisi"
time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
@log
@args_log(user,time)
def add_user(username,password):
    print(f"add user......{username}......{password}")

add_user("admin","<PASSWORD>")

装饰器案例练习

题目

复制代码
"""
    1.请实现一个装饰器,通过一次调用使函数重复执行五次
    2.请实现一个装饰器,每次调用函数时,将函数名字以及调用此函数的时间点写入文件中
    3.完成文件写入功能,任意写入一个字符,编写装饰器,实现写入文件时增加当前系统时间
"""

第一题

python 复制代码
#1.函数的无参装饰器
# def loop_5(func):
#     def wrapper(*args, **kwargs):
#         for i in range(5):
#             func(*args, **kwargs)
#     return wrapper

#2.类的无参类装饰器  __init__ 函数本身 call:装饰器功能
class loop_5():
    #func = 0x1233

    def __init__(self,func):
        self.func = func

    def __call__(self,*args,**kwargs):
        for i in range(5):
            self.func(*args,**kwargs)

@loop_5
def test():
    print("test......")

test()

第二题

python 复制代码
#练习二;
#1.函数的有参装饰器
import time
time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
# def write_file(time):
#     def decorator(func):
#         def wrapper(*args,**kwargs):
#             #写入函数名字和时间点
#             with open("../test.txt","a+",encoding="utf-8") as f:
#                 f.write(f"func_name: {func.__name__},time: {time}\n")
#             func(*args,**kwargs)
#         return wrapper
#     return decorator

#2.类的有参装饰器
class write_file():
    def __init__(self,time):
        self.time = time

    def __call__(self,func):
        def wrapper(*args,**kwargs):
            #写入文件
            with open("../test.txt","a+",encoding="utf-8") as f:
                f.write(f"func_name: {func.__name__},time: {self.time}\n")
            func(*args,**kwargs)
        return wrapper

@write_file(time)
def test2():
    print("test2.....")

test2()

第三题

python 复制代码
#练习3
class write_file2():
    def __init__(self,time):
        self.time = time
    def __call__(self,func):
        def wrapper(*args,**kwargs):
            with open("../test_log2.txt","a+",encoding="utf-8") as f:
                f.write(f"time: {self.time}\n")
            func(*args,**kwargs)
        return wrapper

@write_file2(time)
def test3(str):
    with open("../test_log2.txt","a+",encoding="utf-8") as f:
        f.write(str)
test3("have a luck day\n")
相关推荐
csbysj20202 小时前
Ruby 简介
开发语言
YUJIANYUE2 小时前
asp/php日历式值班查询系统2026版
开发语言·php
Allen_LVyingbo2 小时前
用Python实现辅助病案首页主诊断编码:从数据清洗到模型上线(下)
开发语言·python·安全·搜索引擎·知识图谱·健康医疗
忠实米线2 小时前
使用lottie.js播放json动画文件
开发语言·javascript·json
深蓝电商API2 小时前
Selenium无头浏览器配置与反检测技巧
爬虫·python·selenium
0思必得02 小时前
[Web自动化] Selenium浏览器对象方法(操纵浏览器)
前端·python·selenium·自动化·web自动化
CS创新实验室2 小时前
《计算机网络》深入学:虚拟局域网(VLAN)技术与应用
开发语言·计算机网络·php·vlan·虚拟局域网
H Corey2 小时前
Java抽象类与接口实战指南
java·开发语言·学习·intellij-idea
少控科技2 小时前
QT高阶日记011
开发语言·qt