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
相关推荐
路人与大师6 分钟前
【Mermaid.js】从入门到精通:完美处理节点中的空格、括号和特殊字符
开发语言·javascript·信息可视化
你怎么知道我是队长30 分钟前
C语言---循环结构
c语言·开发语言·算法
o0o_-_1 小时前
【go/gopls/mcp】官方gopls内置mcp server使用
开发语言·后端·golang
Dxy12393102161 小时前
python把文件从一个文件复制到另一个文件夹
开发语言·python
sonrisa_2 小时前
collections模块
python
酷飞飞2 小时前
Qt Designer与事件处理
开发语言·qt·命令模式
折翼的恶魔2 小时前
数据分析:排序
python·数据分析·pandas
天雪浪子2 小时前
Python入门教程之赋值运算符
开发语言·python
Wadli2 小时前
C++语法 | static静态|单例模式
开发语言·c++·单例模式
他们都不看好你,偏偏你最不争气3 小时前
【iOS】AFNetworking
开发语言·macos·ios·objective-c