Python代码为何'c'最先打印,而非先输出优先调用的f()?
为什么实际输出顺序是
cfim而不是以f开头? def f(): print("f") class C: print("c") def __init__(self): print('i') def m(self): print('m') f() C().m()
核心执行逻辑
Python 运行代码时严格遵循从上到下逐行执行可执行语句的规则,不存在函数比类优先级更高的默认排序:
- 碰到
def定义函数时,仅完成函数对象的创建和变量绑定,函数内部的代码必须等被显式调用时才会执行。 - 碰到
class定义类时,会逐行执行整个类缩进块内的所有顶层语句,全部跑完后才完成类对象的创建和变量绑定。这一点和函数的执行逻辑完全不同:类块本质是一个临时命名空间,块内的顶层代码会在类定义阶段直接运行,不需要等到类被实例化的时刻。
逐行执行流拆解
按照代码的书写顺序,实际的运行步骤和对应输出为:
- 执行第一行
def f()语句:创建函数对象,绑定到当前作用域的f变量,函数内部的print("f")暂不执行,无输出。 - 执行
class C:语句,进入类块执行流程:- 运行类块第一行的
print("c"):直接输出c - 运行类块内的
def __init__(self)、def m(self)语句:将两个方法绑定为类C的属性,方法内部的代码暂不执行,无输出。 - 类块执行完毕,完成类C的对象创建,绑定到当前作用域的
C变量,流程回到模块级代码。
- 运行类块第一行的
- 执行模块级的
f()语句:调用已创建完成的f函数,运行内部逻辑,输出f - 执行模块级的
C().m()语句,拆分为两步运行:- 调用类C创建实例,触发
__init__构造方法执行,输出i - 调用实例的
m方法,运行内部逻辑,输出m
最终拼接的输出顺序就是cfim,和实际运行结果完全匹配。
- 调用类C创建实例,触发
预期偏差的来源
之前的认知误区主要有两点:
- 误以为函数的执行优先级高于类定义,但Python没有自定义的优先级规则,代码书写位置越靠上,执行时机就越早。这里
f()的调用语句写在整个类定义代码块的下方,本身就排在类定义的所有逻辑之后。 - 误以为类块内的所有代码都会等类实例化时才运行,但实际上只有写在类的实例方法、构造方法里的代码,才会等实例化或方法被调用时才执行;类块顶层的独立语句,在类被创建(也就是解析执行
class关键字的阶段)就会直接运行。
内容的提问来源于stack exchange,提问作者GMuhammed
相关产品推荐
相关产品推荐

