python装饰器
说到python中的装饰器,面试基本都会问到,而我也是每次面试前看一下,工作后长时间不用又会忘记,学习-忘记-学习-忘记。。。干脆整理为文档,以供后续翻阅、回忆起来方便。
这篇文章不太适合初学者,没有太多解释,就直接上代码,初学者建议找寻别的帖子学习~
基于函数的装饰器
# 无参
def decorator(func):
def wrapper(*arg, **kwargs):
print('装饰器方法')
return func(*arg, **kwargs)
return wrapper
@decorator
def foo():
print('foo 方法执行')
# 带参
def decor_param(level):
def decorator(func):
def wrapper(*arg, **kwargs):
if level == 'D':
print('装饰器方法')
else:
print('=======')
return func(*arg, **kwargs)
return wrapper
return decorator
@decor_param(level='Dw')
def foo():
print('foo 方法执行')
基于类实现的装饰器
# 无参
class Request:
def __init__(self, func):
self.func = func
self.num_calls = 0
def __call__(self, *args, **kwargs):
self.num_calls += 1
print('num of calls is: {}'.format(self.num_calls))
return self.func(*args, **kwargs)
# 定义函数时就会调用init方法,但不会执行call方法
@Request
def example():
print("hello world")
return 10
# 调用函数时才执行call方法,调用多次执行多次,但init只有1次
example()
example()
# 如果需要通过类形式实现带参数的装饰器,那么会比前面的例子稍微复杂一点。
# 那么在构造函数里接受的就不是一个函数,而是传入的参数。通过类把这些参数保存起来。然后在重载__call__方法是就需要接受一个函数并返回一个函数。
class logging(object):
def __init__(self, level='INFO'):
self.level = level
def __call__(self, func): # 接受函数
def wrapper(*args, **kwargs):
print("[{level}]: enter function {func}()".format(
level=self.level,
func=func.__name__))
func(*args, **kwargs)
return wrapper #返回函数
@logging(level='INFO')
def say(something):
print("say {}!".format(something))
say('SB')
装饰器应用-实现单例模式
def Singleton(cls):
cls.instance = None
def _singleton_wrapper(*args, **kargs):
if cls.instance is None:
cls.instance = cls(*args, **kargs)
return cls.instance
return _singleton_wrapper
@Singleton
class Test():
pass
a = Test()
b = Test()
print(a is b) #True
小结
装饰器必须接受一个callable对象,其实它并不关心你返回什么,可以是另外一个callable对象(大部分情况),也可以是其他类对象,比如property。
参考资料
原文地址:https://blog.csdn.net/weixin_50652063/article/details/144013388
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!