python装饰器

python 装饰器

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

装饰器返回值是一个函数;接收参数也是一个函数(参数是我们业务要执行的函数)。

一个简单示例

python 复制代码
#  定义一个简单的装饰器
def a_new_decorator(a_func):
    def wrapTheFunction():
        print("before executing a_func()"
        a_func()
        print("after executing a_func()"
    return wrapTheFunction
              
def a_function():
	print('main func')
            
# 装饰器执行的过程              
a_function = a_new_decorator(a_function)
a_function()

过程:装饰器把要执行的函数作为参数传给自己,在创建一个同名函数对象代替要执行的函数

使用@

python 复制代码
@a_new_decorator
def a_function():
	print('main func')
   
a_function()
# 执行效果同上

functools.wraps

functools.wraps保留原函数的名字和注释文档(docstring)

python 复制代码
from functools import wraps

#  定义一个装饰器
def a_new_decorator(a_func):
    @wraps(a_func)
    def wrapTheFunction():
        print("before executing a_func()"
        a_func()
        print("after executing a_func()"
    return wrapTheFunction

函数参数

参数可以通*args、**kwargs

python 复制代码
from functools import wraps
def decorator_name(f):
    @wraps(f)
    def decorated(*args, **kwargs):
    	if not can_run:
    		return "Function will not run"
    	return f(*args, **kwargs)
    return decorated

@decorator_name
def func(msg:str):
    print(msg)
	return("Function is running")

can_run = True
print(func("hahah"))
# Output: hahah
# Output: Function is running

带参数的装饰器

外层再套一个函数

python 复制代码
from functools import wraps

def logit(logfile='out.log'):
    def logging_decorator(func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
        	log_string = func.__name__ + " was called"
        	print(log_string)
        	# 打开logfile,并写⼊内容
        	with open(logfile, 'a') as opened_file:
        		# 现在将⽇志打到指定的logfile
        		opened_file.write(log_string + '\n')
    	return wrapped_function
    return logging_decorator
python 复制代码
@logit()
def myfunc1():
	pass
myfunc1()
# Output: myfunc1 was called
# 现在⼀个叫做 out.log 的⽂件出现了,⾥⾯的内容就是上⾯的字符串
@logit(logfile='func2.log')
def myfunc2():
	pass

myfunc2()
# Output: myfunc2 was called
# 现在⼀个叫做 func2.log 的⽂件出现了,⾥⾯的内容就是上⾯的字符串

装饰类

类也可以用来构建装饰器

python 复制代码
class logit(object):
    def __init__(self,logfile='out.log'):
        self.logfile = logfile
    # __call__ :可以使用类名调用__call__函数的实现
    def __call__(self,func):
        log_string = func.__name__+" was called"
        print(log_string)
        with open(self.logfile,'a') as open_file:
            open_file.write(log_string+"\n")
        self.notify()
        
    def notify(self):
        # 打印日志
        pass
python 复制代码
@logit()
def func1():
	pass

可以继承logit,扩展功能

python 复制代码
# 来添加email的功能,保留原来的记录日志的功能
class email_logit(logit):
    def __init__(self, email='admin@myproject.com', *args, **kwargs)
        self.email = email
        super(logit, self).__init__(*args, **kwargs)
        
    def notify(self):
        # 打印日志
        # send emil 
        pass
相关推荐
djarmy1 小时前
MAIN.c(1): warning C318: can’t open file ‘STC8G.H’ 报错 解决 分析
c语言·开发语言·mongodb
广州山泉婚姻2 小时前
Python序列号源码分析
python
HEJOO92 小时前
深入理解 Java volatile 关键字:原理、用法与常见误区
java·开发语言·spring
曹牧2 小时前
Java:no content to map due to end of input
java·开发语言
计算机源码社2 小时前
【大数据项目实战】基于大数据的影视内容生态综合质量分析与可视化-基于数据挖掘的影视内容类型共现与口碑聚类分析系统
大数据·人工智能·python·数据挖掘·数据分析·毕业设计·课程设计
梦梦代码精2 小时前
《回收租赁系统技术选型避坑指南:业务闭环与二开自由度详解》
开发语言·低代码·docker·开源·代码规范
C^h2 小时前
pytorch 适合初学者 0基础学习
人工智能·pytorch·python
隔窗听雨眠2 小时前
记一次SQL Server数据库性能分析:从CPU100%到单配置修复的完整诊断
开发语言·数据库·php
David猪大卫2 小时前
【C++修炼】智能指针使用及原理
开发语言·c++·经验分享·笔记·学习·考研·面试
charlie1145141912 小时前
现代Qt开发之图像处理进阶:像素操作与格式转换
开发语言·图像处理·qt