展开的顺序
正如你所预料的那般, 模块级代码(不是任何函数的一部分的代码)在扩展阶段被执行. 有些令人意外的是, 这将发生在所有宏(除了 def)展开之后....这证明编译器首先解析所有标准宏. 然后模块生成开始, 也是在这个阶段, 模块级代码以及对 def 的调用被执行.
模块级友好宏
这对我们自己的宏有一些重要的影响....如果我们想支持对宏的模块级动态调用, 就不应该在宏上下文中做任何假定. 相反, 我们应该将代码生成推迟到调用方的上下文中....因为这段代码将在所有宏展开后运行. 例如, 请记住, 即使我们的宏是从一个推导式中调用的, 它也只会被调用一次. 但是, 宏生成的代码将在推导式中运行 — 对每个元素运行一次....一定要记住 — 在展开阶段, 宏相当于 AST 片段的普通组合. 如果你理解调用者的上下文和宏输入, 那么直接执行转换或在必要时通过延迟执行转换并不算难.
本系列绝不可能涵盖方方面面和所有的细节.