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
相关推荐
o_insist4 分钟前
LangChain1.0 实现 PDF 文档向量检索全流程
人工智能·python·langchain
脑洞AI食验员9 分钟前
智能体来了:用异常与文件处理守住代码底线
人工智能·python
BHXDML9 分钟前
JVM 深度理解 —— 程序的底层运行逻辑
java·开发语言·jvm
Wang's Blog12 分钟前
Nodejs-HardCore: 深入解析DBF文件之二进制文件处理指南
开发语言·nodejs
hoiii18713 分钟前
基于LSB匹配的隐写术MATLAB实现程序
开发语言·matlab
J2虾虾20 分钟前
Java使用的可以使用的脚本执行引擎
java·开发语言·脚本执行
曲幽21 分钟前
FastAPI登录验证:用OAuth2与JWT构筑你的API安全防线
python·fastapi·web·jwt·token·oauth2
幻云201023 分钟前
Next.js指南:从入门到精通
开发语言·javascript·人工智能·python·架构
老马识途2.025 分钟前
java处理接口返回的json数据步骤 包括重试处理,异常抛出,日志打印,注意事项
java·开发语言
CCPC不拿奖不改名31 分钟前
网络与API:从HTTP协议视角理解网络分层原理+面试习题
开发语言·网络·python·网络协议·学习·http·面试