selfteaching / the-craft-of-selfteaching

One has no future if one couldn't teach themself.
15.18k stars 16.38k forks source link

提出了一个错误,装饰器的执行顺序应该是“自上而下”,而不是”自下而上“,同时上传了一张照片用于辅助详细说明,修改照片名称以保证命名格式与其他的照片一致。 #1155

Open awelin opened 5 months ago

awelin commented 5 months ago

装饰器的执行顺序是 “自上而下”,不是 “自下而上” —— 比如在上述例子中,执行'an_output()'时依次发生下述步骤:

  1. 第一次调用'an_output()'的时候调用第一个修饰器strong的返回值wrapper,也就是调用函数'strong(func)'里的函数'wrapper()'。
  2. 在调用函数wrapper()的过程中又需要调用'func()',也就是第二次调用'an_output()'。
  3. 第二次调用'an_output()'的时候调用第二个修饰器uppercase的返回值wrrapper,也就是调用函数'uppercase(func)'里的函数'wrapper()'。
  4. 在调用函数'wrapper()'的过程中又需要调用'func()',也就是第三次调用'an_output()'。
  5. 第三次调用'an_output()'的时候调用第三个修饰器,但没有第三个修饰器了(Python的编译器在定义函数an_output()的时候会数一下有多少个修饰器,通过Debug观察编译器运行的过程可以知道),于是就调用函数an_output()本身。
  6. 调用函数'an_output()'本身得到返回值,将返回值返回到第4步调用处。
  7. 进一步运行得到第3步中调用函数'wrapper()'的返回值,将返回值返回到第2步调用处。
  8. 进一步运行得到第1步中调用函数'wrapper()'的返回值,也就是最终的返回值。 虽然反映出来的效果是 “自下而上” 或者 “由里到外” ,但其实是 ”自上而下“。

我做出以上判断的依据有二:

  1. 通过Debug相关代码观察Python编译器的编译次序可以得出以上结论。
  2. 这样解释装饰器的执行顺序在逻辑上确实更讲得通。