IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python装饰器的使用 -> 正文阅读

[Python知识库]Python装饰器的使用

1 装饰器

1.2 函数装饰器

所谓的装饰器,其实是通过装饰器函数,来修改原函数的一些功能,而原函数本身并不进行修改。
在这里插入图片描述
下面的示例中,使用装饰器在原函数前进行打印语句。

import functools

def my_decorator(func):
    @functools.wraps(func) # 将原函数func的元信息,拷贝到wrapper中的
    def wrapper(*args,**kwargs):
        print('this is a wrapper')
        func(*args)
    return wrapper

@my_decorator # @为语法糖
def greet(name):
    print('welcome {}!'.format(name))

@my_decorator
def greet_two(name1,name2):
    print('welcome {} and {}!'.format(name1,name2))

greet([5,24,2])
greet_two([5,24,2],'234')

# 如果不适用functools.wraps装饰器,原函数中的元信息将会被改变
print(greet.__name__)
print(help(greet))
this is a wrapper
welcome [5, 24, 2]!
this is a wrapper
welcome [5, 24, 2] and 234!
greet
Help on function greet in module __main__:

greet(name)

None

使用装饰器将会修改原函数的元信息,我们可以通过系统装饰器functools.wraps来保持元信息。

1.2 类装饰器

"""
类装饰器的使用
"""
class Count():
    def __init__(self,func):
        self.func=func
        self.num=0

    def __call__(self, *args, **kwargs):
        self.num+=1
        print('num:{}'.format(self.num))
        self.func(*args,**kwargs)

@Count
def example(message):
    print('message:{}'.format(message))

example('hello')

example('nihao')
num:1
message:hello
num:2
message:nihao

1.3 使用多个装饰器

我们可以对一个函数使用多个装饰器,顺序为从内到外。

import functools

def decorator1(func):
    @functools.wraps(func)
    def wrapper(*args,**kwargs):
        print('decorator one')
        func(*args,**kwargs)
    return wrapper

def decorator2(func):
    @functools.wraps(func)
    def wrapper(*args,**kwargs):
        print('decorator two')
        func(*args,**kwargs)
    return wrapper

@decorator1
@decorator2
def greet(message):
    print('message:',message)

greet('hello world')
decorator one
decorator two
message: hello world

1.4 案例

1.4.1 案例1-发表评论

在博客网站或是视频网站发表评论前,我们要先检测用户是否登录,确认登陆后才能发表评论。在此使用装饰器进行登陆的检测。

"""
用装饰器实现:
发表评论前检测是否登录,已登录则发表评论,否则抛出异常
"""
import functools

def check_user_logged_in(request):
    return 1 if request>10 else 0

def authenticate(func):
    @functools.wraps(func)
    def wrapper(*args,**kwargs):
        request=args[0]
        if check_user_logged_in(request): # 如果用户是登录状态
            func(*args,**kwargs) # 执行方法post_comment()
        else:
            raise Exception('Authentication failed')
    return wrapper

@authenticate
def post_comment(request, comment):
    print('comment successfully:',comment)

post_comment(11,'what a wonderful blog!')
comment successfully: what a wonderful blog!

1.4.2 案例2-记录执行时间

通过装饰器,我们可以记录任意函数的执行时间。

"""
案例2:使用装饰器实现测试任意函数的执行时间
"""
import functools
import time

def log_execute_time(func):
    @functools.wraps(func)
    def wrapper(*args,**kwargs):
        start=time.time()
        func(*args,**kwargs)
        end=time.time()
        print('time cost:%.2f' %(end-start))
    return wrapper

@log_execute_time
def calculate_similarity():
    count=1
    for i in range(int(1e6)):
        count+=1

calculate_similarity()

time cost:0.08

1.4.3 案例3-参数合理性检测

在训练神经网络模型时,这个过程往往是非常耗时的,如果花费了几个小时,最后因为参数的不合理而产生报错,就会对资源造成极大的浪费。
在此我们使用装饰器对训练参数进行合理性检测。

"""
在神经网络模型进行训练前,进行参数合理性检查
"""
import functools

def validation_check(func):
    @functools.wraps(func)
    def wrapper(*args,**kwargs):# 这里进行简单的输入类型检查
        for idx,param in enumerate(args):
            if not isinstance(param,float):
                raise Exception('Parameter format wrong in pos:{}'.format(idx+1))
        for idx,key in enumerate(kwargs):
            if key=='optimizer' and kwargs[key] not in ['Adam','SGD']:
                raise Exception('Keyword parameter format wrong in pos:{}'.format(idx+1+len(args)))
        func(*args,**kwargs)
    return wrapper

@validation_check
def neural_network_training(l2,lr,dropout,optimizer='SGD'):
    print('start training...')
    print('l2:{}'.format(l2))
    print('learning rate:{}'.format(lr))
    print('dropout rate:{}'.format(dropout))
    print('optimizer:{}'.format(optimizer))

neural_network_training(0.5,0.001,0.2,optimizer='SGD')
start training...
l2:0.5
learning rate:0.001
dropout rate:0.2
optimizer:SGD
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:45:38  更:2022-03-21 20:48:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 19:28:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码