Python中如何理解代码执行顺序的问题?
from types import FunctionType
def tracer(func):
calls = 0
def onCall(*args, **kwargs):
nonlocal calls
calls += 1
print(‘call %s to %s’ % (calls, func.name)) #语句 1
return func(*args, **kwargs) #语句 2
return onCall
class MetaTrace(type):
def new(meta, classname, supers, classdict):
for attr, attrval in classdict.items():
print(‘attr=%s ,attrval=%s’%(attr,attrval))
if type(attrval) is FunctionType:
classdict[attr] = tracer(attrval) #语句 3
return type.new(meta, classname, supers, classdict)
class Person(metaclass=MetaTrace):
def init(self, name, pay):
print(“Person init,name=”,name)
self.name = name
self.pay = pay
def giveRaise(self, percent):
print(“Person giveRaise,percent=”,percent)
self.pay *= (1.0 + percent)
def lastName(self):
print(“Person lastName,self=”,self)
return self.name.split()[-1]
print(’-----------------’)
bob = Person(‘Bob Smith’, 50000)
上面代码输出如下:
attr=module ,attrval=main
attr=qualname ,attrval=Person
attr=init ,attrval=<function Person.init at 0x01C2BBB8>
attr=giveRaise ,attrval=<function Person.giveRaise at 0x01C2BB70>
attr=lastName ,attrval=<function Person.lastName at 0x01C2BB28>
call 1 to init
Person init,name= Bob Smith
我的问题是:
执行语句 3 时,当执行到 classdict[init] = tracer(<function Person.init at 0x01C2BBB8>) 时,为何不会立即去执行 tracer 定义中的语句 1 和语句 2,使得__init__方法的结果赋值给 classdict[init] ?
Python中如何理解代码执行顺序的问题?
Python代码的执行顺序遵循“从上到下,逐行执行”的基本规则,但有几个关键点会改变这个顺序,理解它们就抓住了核心:
- 模块导入:
import语句会首先执行被导入模块的全部顶层代码。 - 函数与类定义:
def和class语句只是定义,其中的代码在函数被调用或类被实例化时才会执行。 - 流程控制:
if/elif/else、for、while、try/except会根据条件改变执行路径。 - 函数调用:遇到函数调用时,执行会跳转到函数内部,执行完毕后再返回。
- 生成器与异步:
yield和async/await会让执行权暂时挂起和让出,这是最需要留意的“顺序陷阱”。
看个例子就明白了:
print("1. 模块顶层代码开始")
def my_func():
print("3. 函数内的代码执行")
return True
if __name__ == "__main__":
print("2. 主条件块开始")
result = my_func()
print(f"4. 回到主块,收到结果: {result}")
print("5. 模块顶层代码结束")
输出顺序就是1, 2, 3, 4, 5。记住定义不等于执行,调用才会触发。
总结:脑子里跟着解释器走一遍,重点盯住函数调用和流程跳转点。
语句 1,2 是 oncall 函数的语句,oncall 执行时才会执行

