装饰器原理python_Python 装饰器原理、定义与用法详解

本文详细介绍了Python装饰器的原理、定义和使用方法。装饰器允许我们在不修改函数源代码的情况下,增加或修改其功能。通过示例展示了如何创建和使用装饰器,以及如何利用`functools.wraps`保持被装饰函数的元信息。此外,还探讨了装饰器在授权、日志记录等场景的应用,并展示了如何将装饰器设计为类,以实现更复杂的逻辑。最后,通过电子邮件日志装饰器展示了装饰器的灵活性和可扩展性。
摘要由CSDN通过智能技术生成

本文实例讲述了python 装饰器原理、定义与用法。分享给大家供大家参考,具体如下:

Python 装饰器

一、何为装饰器

1、在函数中定义函数

在函数中定义另外的函数,就是说可以创建嵌套的函数,例子如下 def sayHi(name="hjj2"):

print 'inside sayHi() func'

def greet():

return 'inside greet() func'

print(greet())

sayHi()

#output

# inside sayHi() func

# inside greet() func

2、将函数作为参数传给另外一个函数,装饰器原型 def sayHi():

return 'hi hjj2'

def doSthBeforeSayHi(func):

print 'before sayHi func'

print(func())

doSthBeforeSayHi(sayHi)

#output

# before sayHi func

# hi hjj2

3、实现一个装饰器

在第二步中,我们已经基本探究到装饰器的原理了,python装饰器做的事就是通过封装一个函数并且用这样或那样的方式来修改它的行为。不带@的初步示例如下: def new_decorator(func):

def wrapDecorator():

print 'before func'

func()

print 'after func'

return wrapDecorator

def func_require_decorator():

print 'a func need decorator'

func_require_decorator()

#ouput: a func need decorator

func_require_decorator = new_decorator(func_require_decorator)

func_require_decorator()

#ouput:

# before func

# a func need decorator

# after func

使用@来运行装饰器 @new_decorator

func_require_decorator()

#ouput:

# before func

# a func need decorator

# after func

这里我们可以看到,这两个例子的运行结果是一样的。所以我们能想象得到@new_decorator的作用就是 func_require_decorator = new_decorator(func_require_decorator)

我们继续优化这个装饰器,现在我们有一个问题就是,如果我们想要通过print(func_require_decorator.__name__)就会报错# Output: wrapTheFunction。这样就需要借助python提供的functools.wraps来解决了

@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。 from functools import wraps

def new_decorator(func):

@wraps(func)

def wrapDecorator():

print 'before func'

func()

print 'after func'

return wrapDecorator

def func_require_decorator():

print 'a func need decorator'

@new_decorator

func_require_decorator()

print(func_require_decorator.__name__)

#ouput: func_require_decorator

二、使用场景

1、授权,大体例子 from functools import wraps

def requires_auth(f):

@wraps(f)

def decorated(*args, **kwargs):

auth = request.authorization

if not auth or not check_auth(auth.username, auth.password):

authenticate()

return f(*args, **kwargs)

return decorated

2、日志: 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)

with open(logfile,'a') as opened_file:

opened_file.write(log_string+'\n')

return func(*args,**kwargs)

return wrapped_function

return logging_decorator

@logit()

def func1():

pass

func1()

3、其他如flask中的@app.route()

三、装饰器类

1、将上面的日志装饰器变为类的初步模型如下 from functools import wraps

class logit(object):

def __init__(self, logfile='out.log'):

self.logfile = logfile

def __call__(self, func):

@wraps(func)

def wrapped_function(*args, **kwargs):

log_string = func.__name__ + "was called"

print(log_string)

# 打开logfile并写入

with open(self.logfile, 'a') as open_file:

# 将日志写到指定文件

open_file.write(log_string + '\n')

# 发送一个通知

self.notify()

return func(*args, **kwargs)

return wrapped_function

def notify(self):

pass

@logit()

def myfunc1():

pass

class email_logit(logit):

'''

实现在函数调用时发送email

'''

def __init__(self, email='admin@xxx.com', *args, **kwargs):

self.email = email

super(email_logit, self).__init__(*args, **kwargs)

def notify(self):

'''

发送邮件通知

'''

pass

通过这种方式,我们可以定义我们在自己的需求,减少代码的冗余,提高复用率。

至此,关于装饰器的探索就结束啦。

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python面向对象程序设计入门与进阶教程》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python编码操作技巧总结》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值