Python中关于装饰器中__init__方法的问题
第一个装饰器的代码:
registry = []
def register(func):
def __init__(self):
print("INIT!!!")
print('running register(%s)' % func)
registry.append(func)
return func
[@register](/user/register)
def f1():
print('running f1()')
def main():
print('registry ->', registry)
f1()
if name =='main':
main()
上面代码的输出如下,可见装饰器的__init__方法并没有执行:
running register()
registry -> []
running f1()
第二个装饰器的代码:
class tracer(object):
def __init__(self, func):
print("tracer: init")
self.func = func
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
class C:
def __init__(self):
pass
@tracer
def f(self):
print("run f!")
print("--------------")
输出如下:
tracer: init
我的问题是,这两个装饰器为何第一个装饰器的__init__方法没有执行,而第二个装饰器的__init__方法却被执行了?
Python中关于装饰器中__init__方法的问题
def a():
def b():
print(“emmmmmmm”)
print(“oh yep”)
a()
为什么 b 没有被执行?
我无法理解你的问题
楼主发下一个帖子前记得看看 markdown…看一眼预览再发帖…
我是看过预览才发的,我用论坛用不太好,比如 name 前后各有两个下划线没有显示出来,因为着急问问题,想着这不影响整体阅读就没有去改了
不是很明白,您的例子中因为没有 b()这样的调用语句,自然 b 不会被执行。可我的例子中第一个装饰器是执行了 register(f1()),这时 register.init()应该被执行的吧?
感谢指点,我晕了,register 是函数不是类!顺便问个问题,所谓的函数装饰器,是说装饰器是一个函数,还是说被装饰的对象是函数呢?
函数装饰器 这只是个中文词汇,有歧义,所以不用太在意。
你只需要知道装饰器可以是一个类也可以是一个函数,被装饰的可以使一个类也可以是一个函数
这边有我总结的装饰器相关的两篇文章,希望可以帮到你。
http://45.32.54.6/2017/04/17/Decorators-for-Class
http://45.32.54.6/2017/04/17/Decorators-for-Functions-and-Methods
http://coolshell.cn/articles/11265.html
check this out!
decorator 只是个 AOP 的糖(
AOP 是什么的缩写呢?语法?
感谢指点,关于装饰器我另外还发了一个问题求指点,如果有空的话,能否看看我发的帖子,点拨我一下呢,谢谢了! https://www.v2ex.com/t/384418#reply2
感谢!
#9 面向切面编程
谢谢你的总结,我看了一下,似乎有点问题。你的被装饰的类似乎没必要重载__new__方法吧,如果要的话,应该使用新式类 class A(object),否则__new__不会被调用。
首先,我的代码是 Python3 代码,不存在新式类和旧式类之分,不管怎么声明,都是新式类。其次,我重载__new__方法是来看调用顺序,没别的用处。
关于您写的这篇文章 http://45.32.54.6/2017/04/17/Decorators-for-Functions-and-Methods/。
我看“ 2.1 函数不带参数”小节中,装饰器的效果等同于 echo()=Decorator.call() ,所以等号的右边,即 Decorator.call()运行后应该要返回一个函数才对吧?
但是为何__call__方法直接就执行 self.fun(),而不是 return self.fun 呢?
关于您的类的装饰器这篇 http://45.32.54.6/2017/04/17/Decorators-for-Class/,
例子“ 1.3 装饰器带参数 2 ”,既然 A() = Decorator(1,2).call() ,那为何__call__方法不返回一个对象,而是返回方法 wrapper,这样等号两边的对象不会不匹配么?
统一回复,装饰器的目的是利用语法糖,以不改变原有函数的功能为原则,额外增加一些逻辑。
你的这两个问题,执行一下代码,你自己就会明白。建议你按照你自己的想法,修改我的代码,看出来的结果区别在哪里,这样就会明白为什么要那样写。

