第一个装饰器的代码:
registry = []
def register(func):
    def __init__(self): 
        print("INIT!!!") 
    print('running register(%s)' % func)   
    registry.append(func)   
    return func   
@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__方法却被执行了?
|  |      1Kilerd      2017-08-21 22:17:58 +08:00 via iPhone def a(): def b(): print("emmmmmmm") print("oh yep") a() 为什么 b 没有被执行? | 
|  |      2Trim21      2017-08-21 22:20:04 +08:00 楼主发下一个帖子前记得看看 markdown...看一眼预览再发帖... | 
|      3saximi OP @Trim21 我是看过预览才发的,我用论坛用不太好,比如 name 前后各有两个下划线没有显示出来,因为着急问问题,想着这不影响整体阅读就没有去改了 | 
|      4saximi OP @Kilerd 不是很明白,您的例子中因为没有 b()这样的调用语句,自然 b 不会被执行。可我的例子中第一个装饰器是执行了 register(f1()),这时 register.__init__()应该被执行的吧? | 
|      5saximi OP @Kilerd 感谢指点,我晕了,register 是函数不是类!顺便问个问题,所谓的函数装饰器,是说装饰器是一个函数,还是说被装饰的对象是函数呢? | 
|      6enomine      2017-08-21 23:23:10 +08:00  1 函数装饰器  这只是个中文词汇,有歧义,所以不用太在意。 你只需要知道装饰器可以是一个类也可以是一个函数,被装饰的可以使一个类也可以是一个函数 这边有我总结的装饰器相关的两篇文章,希望可以帮到你。 http://45.32.54.6/2017/04/17/Decorators-for-Class http://45.32.54.6/2017/04/17/Decorators-for-Functions-and-Methods | 
|  |      7garfieldWu      2017-08-21 23:29:35 +08:00 http://coolshell.cn/articles/11265.html check this out! | 
|      8lrxiao      2017-08-21 23:40:04 +08:00 decorator 只是个 AOP 的糖( | 
|      10saximi OP @enomine 感谢指点,关于装饰器我另外还发了一个问题求指点,如果有空的话,能否看看我发的帖子,点拨我一下呢,谢谢了!  https://www.v2ex.com/t/384418#reply2 | 
|      11saximi OP @garfieldWu 感谢! | 
|      13lovestudykid      2017-08-22 07:30:39 +08:00 @enomine 谢谢你的总结,我看了一下,似乎有点问题。你的被装饰的类似乎没必要重载__new__方法吧,如果要的话,应该使用新式类 class A(object),否则__new__不会被调用。 | 
|      14enomine      2017-08-22 10:27:54 +08:00 @lovestudykid 首先,我的代码是 Python3 代码,不存在新式类和旧式类之分,不管怎么声明,都是新式类。其次,我重载__new__方法是来看调用顺序,没别的用处。 | 
|      15saximi OP | 
|      16saximi OP @enomine 关于您的类的装饰器这篇 http://45.32.54.6/2017/04/17/Decorators-for-Class/, 例子“ 1.3 装饰器带参数 2 ”,既然 A() = Decorator(1,2).__call__() ,那为何__call__方法不返回一个对象,而是返回方法 wrapper,这样等号两边的对象不会不匹配么? | 
|      17enomine      2017-08-28 19:56:31 +08:00 @saximi  统一回复,装饰器的目的是利用语法糖,以不改变原有函数的功能为原则,额外增加一些逻辑。 你的这两个问题,执行一下代码,你自己就会明白。建议你按照你自己的想法,修改我的代码,看出来的结果区别在哪里,这样就会明白为什么要那样写。 |