关于修饰器,请问教程中的代码为什么不能进一步简化?

2016-09-01 19:47:24 +08:00
 Newyorkcity
因为不会用社区的语法来缩进,所以只能放图,望谅解
这个是自学的教程上提供的代码:


我觉得 warpper 这一层的存在没有必要,可以简化掉
因为加了装饰器之后 now() = log(text)(now)()对吧
那 log(text)(now)()在 Log 函数执行完后变成 decorator(now)()
此时直接让 decorator(now)执行完成变为 now()不就可以了么?
所以直接让 decorator 的 return 为 func 不就结了?

尝试了一下,是可以输出我想要的东西的...这样我就更加不明白了

请问我的想法哪里错了呢?谢谢.
2880 次点击
所在节点    Python
25 条回复
sherlocktheplant
2016-09-01 20:05:29 +08:00
区别在于你的写法访问不到参数
sherlocktheplant
2016-09-01 20:08:36 +08:00
我的意思是你的装饰器里访问不到参数 比如 如果要求装饰器可以拦截或者篡改某些参数 你的写法做不到
kkzxak47
2016-09-01 20:13:29 +08:00
无参数装饰器可以像你那样写
Newyorkcity
2016-09-01 20:14:27 +08:00
@sherlocktheplant 请问你说的参数是给 @log()用的还是给被修饰的函数用的?

能否以'要求装饰器可以拦截或者篡改某些参数'出一道题?
谢谢
Newyorkcity
2016-09-01 20:15:36 +08:00
@kkzxak47
@log('execute')
这个形式不已经是一个传入了参数的修饰器么?
谢谢
fds
2016-09-01 20:19:11 +08:00
原来的 wrapper 可以记录或者修改 args kw
sherlocktheplant
2016-09-01 20:24:08 +08:00
@Newyorkcity
比如说 要求将所有传入被修饰函数的字符串全部变成大写
sherlocktheplant
2016-09-01 20:26:38 +08:00
第一层是用来接受修饰器本身的参数 第二层是接受被修饰的函数的引用 第三层是接受被修饰函数被调用时接受的参数
tmackan
2016-09-01 20:28:50 +08:00
junnplus
2016-09-01 21:54:26 +08:00
return func 之后,你的 f 函数的 s 参数并不会被返回的 func 接受
KDr2
2016-09-01 22:03:59 +08:00
楼上的诸位,难道不是楼主的第二种写法,只在代码加载时做了 log ,每次 call 的时候并不 log ?
firemiles
2016-09-01 22:39:19 +08:00
楼主你的 log 只是在定义时起作用输出一次,调用的时候跟没装 log 一样
sherlocktheplant
2016-09-01 22:48:13 +08:00
@KDr2
@firemiles

抱歉 很久没写 python 半桶水了
Newyorkcity
2016-09-01 22:54:42 +08:00
@KDr2
@firemiles
额?为什么这么说?
我最后一行的那个 f(5)是调用吗?结果在打印 5 之前得到了 call f()啊?
谢谢..
firemiles
2016-09-01 23:00:12 +08:00
@Newyorkcity 你多屌用几次 f(5)试试,应该只能输出一次 log
firemiles
2016-09-01 23:00:29 +08:00
@Newyorkcity 你多调用几次 f(5)试试,应该只能输出一次 log
iptux
2016-09-01 23:04:37 +08:00
/t/208738 历史总是惊人般的相似
Newyorkcity
2016-09-02 09:02:14 +08:00
@firemiles
是的,尝试了一下发现只有在第一次调用函数才会出现 call f() 然后教程的代码每次都会出现 call f()
可是请问这是为什么呢?
加上了装饰器的话不就令 f = log(text)(f)了么
那每次执行 f()都等于在自行 log(text)(f)()吧...为什么会出现之后的调用无效的问题呢
firemiles
2016-09-02 09:26:37 +08:00
@Newyorkcity 你装饰器返回的是原函数 `f = f`,不是 wrapper ,所以你的装饰器没有效果,例子多一层 'f = wrapper';
Newyorkcity
2016-09-02 09:33:28 +08:00
@firemiles 大致懂了,谢谢~!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/303301

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX