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
相关推荐
Knight_AL32 分钟前
浅拷贝与深拷贝详解:概念、代码示例与后端应用场景
android·java·开发语言
枫叶丹434 分钟前
【Qt开发】输入类控件(六)-> QDial
开发语言·qt
AI小云1 小时前
【Python与AI基础】Python编程基础:模块和包
人工智能·python
思考的笛卡尔1 小时前
Go语言实战:高并发服务器设计与实现
服务器·开发语言·golang
努力努力再努力wz1 小时前
【C++进阶系列】:万字详解智能指针(附模拟实现的源码)
java·linux·c语言·开发语言·数据结构·c++·python
凤年徐1 小时前
【C++】string的模拟实现
c语言·开发语言·c++
敲代码的嘎仔1 小时前
JavaWeb零基础学习Day2——JS & Vue
java·开发语言·前端·javascript·数据结构·学习·算法
吃鱼吃鱼吃不动了1 小时前
什么是负载均衡?
开发语言·php
小蕾Java2 小时前
Python详细安装教程(附PyCharm使用)
开发语言·python·pycharm
weixin_307779132 小时前
AWS云上ClickHouse数据仓库部署方案详解
开发语言·clickhouse·自动化·云计算·aws