🎉🎉🎉欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的更新文章!!!🙏🙏🙏
@[toc]
装饰器的定义
在代码运行期间,要增强函数的功能,但是又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为"装饰器"(Decorator)
使用方法
decorator
,接受一个函数作为参数,并返回一个函数。我们要借助Python
的@
语法,把decorator
置于函数的定义处:
import time
import functools
def metric(text):
def dec(func):
@functools.wraps(func)
def wapp(*args, **kwargs):
f = time.time()
fn = func(*args, **kwargs)
l = time.time()
print(func.__name__, text, l - f)
return fn
return wapp
return dec
@metric('执行时间')
def fast(x, y):
time.sleep(1)
return x + y
f = fast
print(f(1, 2))
结果返回:
fast 执行时间 1.000016212463379
3
fast
这里需要注意的是 functools.wraps(func)
。
在没有加上 functools.wraps(func)
时, 结果会返回:
fast 执行时间 1.0045192241668701
3
wapp
可以发现函数名变为了装饰器函数名,原来函数自身信息丢失!😱
这样在一些特殊情况执行就会出错。为了解决这个问题,我们可以借助Python
内置的functools.wraps()
。
@property 装饰器
Python 提供了 property 装饰器,被装饰的方法,我们可以将其『当作』属性来用,看下面的例子:
class Exam(object):
def __init__(self, score):
self._score = score
@property
def score(self):
return self._score
@score.setter
def score(self, val):
if val < 0:
self._score = 0
elif val > 100:
self._score = 100
else:
self._score = val
>>> e = Exam(60)
>>> e.score
60
>>> e.score = 90
>>> e.score
90
>>> e.score = 200
>>> e.score
100
在上面,我们给方法 score 加上了 @property,于是我们可以把 score 当成一个属性来用,此时,又会创建一个新的装饰器 score.setter,它可以把被装饰的方法变成属性来赋值。
另外,我们也不一定要使用 score.setter 这个装饰器,这时 score 就变成一个只读属性了:
class Exam(object):
def __init__(self, score):
self._score = score
@property
def score(self):
return self._score
>>> e = Exam(60)
>>> e.score
60
>>> e.score = 200 # score 是只读属性,不能设置值
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-676-b0515304f6e0> in <module>()
----> 1 e.score = 200
AttributeError: can't set attribute
- @property 把方法『变成』了属性。
Hi👋,这里是瑞雨溪一个喜欢JavaScript和Vue的大学生,如果我的文章给你带来的帮助,欢迎您关注我,我会持续不断的更新更多优质文章.你的关注就是我的动力!!!🎉🎉🎉