python - 修饰函数
Python 装饰器(Decorator) ,名字叫装饰器,功能自然对应于设计模式中的装饰者模式(代理模式)。
写法上,很像 java 中的函数注解,实际上,功能也大致一样。
简单说:就是在调用函数的时候,可以在在调用之前,加一点逻辑,调用完加一些逻辑,出现异常时加一些逻辑。
用途很多:入参的校验,异常处理,返回值格式转换,等等等。
装饰器
不带参数的装饰者
# 固定的写法
def logger(func):
# 内部函数
def debug(a, b):
# try...catch... 经典代码结构
try:
if b == 0:
raise Exception('by zero!')
return func(a, b)
except Exception as e:
print(e)
raise e
return debug
@logger
def div(a,b):
return a/b
print(div(1, 1))
带参数的装饰者
def logger(level):
# 固定的写法
def decorator(func):
# 内部函数
def debug(a, b):
# try...catch... 经典代码结构
try:
if b == 0:
raise Exception('by zero!')
return func(a, b)
except Exception as e:
print(e)
raise e
# 根据入参,选择对应的处理程序
if level == 'debug':
return debug
else:
raise Exception('level is undefined!')
return decorator
@logger('debug')
def div(a,b):
return a/b
print(div(1, 1))
反射相关
看前面两个案例,会产生几个问题:
一个通用的装饰者要怎么写?该如何获取代码本身的信息呢?
比如说日志:我们至少要知道,代码报错时,它的函数名是啥,入参值是啥。
注意:下面代码有些是通过解析注解实现的,注解不是百分百可靠的
比如:返回值注解填 int,函数实际可以返回 str,这种挂羊头卖狗肉的代码,代码只会警告,但是不影响执行
import inspect
def get_arg_names(func):
# 使用inspect.signature获取函数签名
sig = inspect.signature(func)
# 使用Parameter.name属性获取参数名
return [param.name for param in sig.parameters.values()]
def get_return_type(func):
# 使用signature来获取函数签名
sig = inspect.signature(func)
# 使用return_annotation来获取函数返回值注解
return_annotation = sig.return_annotation
# 如果返回值注解是一个类型提示,我们可以通过__origin__获取原始类型
if hasattr(return_annotation, '__origin__'):
return return_annotation.__origin__
return return_annotation
def get_function_source(func):
# 获取原始函数对象
original = func.__wrapped__ if hasattr(func, '__wrapped__') else func
# 获取原始函数的源代码信息
print(inspect.getsourcelines(original)[0])
# 获取原始函数的源代码行号
print(inspect.getsourcelines(original)[1])
# 固定的写法
def logger(func):
# 内部函数
def debug(*args, **kwargs):
# try...catch... 经典代码结构
try:
# 获取函数名
print(func.__name__)
# 获取参数名
print(get_arg_names(func))
# 获取文件信息
get_function_source(func)
# 获取参数值
print(args)
print(kwargs)
return func(*args, **kwargs)
except Exception as e:
print(e)
raise e
return debug
@logger
def div(a, b):
return a / b
print(div(1, 1))
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY