|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
Python的很多源码里经常会看到
- @abc
- def f():
- return 'fishc'
复制代码
这样的语句。
其中紧跟在@后面的就是装饰器了。
在说装饰器之前,先来看看闭包这个东西。
小甲鱼老师在20讲时说过闭包,课后题传送门。
搞明白这段:
- def funOut():
- def funIn():
- print('宾果!你成功访问到我啦!')
- return funIn()
复制代码
怎么访问到 funIn?
答案是:
------
- def funOut():
- def funIn():
- print('宾果!你成功访问到我啦!')
- return funIn
复制代码
怎么访问到 funIn?
答案是:
区别在于 funOut后面跟了一个()与两个()。
funOut,funIn是函数。
funOut(),funIn()呢,是执行函数。
如果你打印funOut你会看到一串内存地址,
funOut()你会看到这个函数执行后的返回值。
进阶的需求。
有这么一个函数。
- def html_content():
- return 'i love fishc.'
复制代码
这个函数返回 'i love fishc.',
现在我们需要将这串字符串放在p标签, b标签与em标签下组成<p><b><em>i love fishc.</em></b></p>。
很简单嘛,
- def html_content():
- return '<p><b><em>i love fishc.</em></b></p>'
复制代码
这时我们又需要将这串字符串放在a标签下组成<a>i love fishc.</a>。
然后我们再次更改html_content函数。
这时又一个人需要把它放在div标签下。
如果我们只有几行代码还很容易修改,当代码多了之后,修改源代码并不划算。
这时候,我们就可以用装饰器来完成这个工作。
- def add_em(func1):
- def funin():
- return '<em>{0}</em>'.format(func1())
- return funin
复制代码
我们定义一个叫add_em的新函数。
作用自然是添加一个em标签。
同时我们将原始html_content函数上面放上装饰器。
- @add_em
- def html_content():
- return 'i love fishc.'
- print(html_content())
复制代码
你觉得会出现什么?
没错就是变成这样了。
我们没有修改原始代码就实现了修改原始代码的需求!
原理是什么?
@add_em 相当于 add_em(html_content)
之后我们调用 html_content时,就变成了这样。
html_content()
首先 add_em(html_content) - > funin 函数。
之后 funin + () -> funin() 执行函数。
如法炮制!
- def add_em(func1):
- def funin():
- return '<em>{0}</em>'.format(func1())
- return funin
- def add_b(func1):
- def funin():
- return '<b>{0}</b>'.format(func1())
- return funin
- def add_p(func1):
- def funin():
- return '<p>{0}</p>'.format(func1())
- return funin
- @add_p
- @add_b
- @add_em
- def html_content():
- return 'i love fishc.'
- print(html_content())
复制代码
- <p><b><em>i love fishc.</em></b></p>
复制代码
不仅完成了需求,代码也很简洁,还可以重用!
参数!参数!
很多情况下函数都是有参数的,装饰器怎么带参数嘛。
- def html_content(arg):
- return 'i love fishc.{0}'.format(arg)
复制代码
只需要将内层函数加上参数就好了。
- def add_em(func1):
- def funin(arg):
- return '<em>{0}</em>'.format(func1(arg))
- return funin
复制代码
为什么会是这样?
上面说到 加上装饰器之后其实就是变成
add_em(html_content)(arg),
对应返回 funin (arg)
那么就是给内层函数加上参数咯,两个,三个,n个都是这样。
装饰器是否可以被执行?
- def add_em(func1):
- def funin(arg):
- def funinin(arg):
- return '<em>{0}</em>'.format(func1(arg))
- return funinin
- return funin
- def a(arg):
- return '5'
- @add_em(a)
- def html_content(arg):
- return 'i love fishc.{0}'.format(arg)
复制代码
我们知道了@add_em就是 add_em(html_content),
那@add_em(a)也就变成了add_em(a)(html_content),
那是否也会向函数一样可以加多个()表示执行?
答案是否定的,会提示语法错误。
- @add_em(a)(a)
- @add_em(a)(a)
- ^
- SyntaxError: invalid syntax
复制代码
|
评分
-
参与人数 3 | 荣誉 +20 |
鱼币 +20 |
贡献 +18 |
收起
理由
|
SixPy
| + 5 |
+ 5 |
+ 5 |
热爱鱼C^_^ |
冬雪雪冬
| + 10 |
+ 10 |
+ 10 |
感谢楼主无私奉献! |
拈花小仙
| + 5 |
+ 5 |
+ 3 |
感谢楼主无私奉献! |
查看全部评分
|