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
相关推荐
ZSYP-S19 分钟前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos23 分钟前
c++------------------函数
开发语言·c++
程序员_三木35 分钟前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
是小崔啊1 小时前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
tianmu_sama1 小时前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
黄公子学安全1 小时前
Java的基础概念(一)
java·开发语言·python
liwulin05061 小时前
【JAVA】Tesseract-OCR截图屏幕指定区域识别0.4.2
java·开发语言·ocr
jackiendsc1 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
Oneforlove_twoforjob1 小时前
【Java基础面试题027】Java的StringBuilder是怎么实现的?
java·开发语言
羚羊角uou1 小时前
【C++】优先级队列以及仿函数
开发语言·c++