Python 函数定义时即执行:类型提示与默认值的隐藏陷阱

陆景行
陆景行
发布时间:2026-10-14 | 2人浏览过
原创

本文揭示Python函数定义时即执行代码的机制,重点分析类型提示和默认赋值中的表达式会在定义阶段而非调用阶段运行。通过可变对象(如列表)作为默认参数的案例,展示由此引发的状态共享Bug,并提供获取函数注解与默认值的正确方法,帮助开发者规避常见陷阱。

Python函数定义时的隐藏执行机制

在Python中,通常认为只有调用函数时,其内部代码才会执行。然而,一个鲜为人知的事实是:在定义函数时,部分代码实际上已经开始运行。本文将深入探讨这一特性及其潜在影响。

在Python中,通常认为只有调用函数时,其内部代码才会执行。然而,一个鲜为人知的事实是:在定义函数时,部分代码实际上已经开始运行。本文将深入探讨这一特性及其潜在影响。

首先,让我们通过一段代码来直观展示这一现象。

类型提示与默认值的执行时机


def do_something(opt: print('参数 opt'), arg=print('参数 arg')) -> print('函数的返回值'): 
    print("do something runing") 
 
if __name__ == '__main__': 
    pass 

在上述代码中,我们仅定义了函数而未进行调用。此时,程序是否会输出任何信息呢?

答案是肯定的。无论是参数列表中的类型提示、默认值赋值,还是返回值的类型提示,其中的表达式都会在函数定义阶段被立即执行。具体运行结果如下所示:

这种机制在实际开发中较为少见。如果将 print 替换为文件打开或数据库连接等操作,这些动作同样会在定义时触发,可能导致资源提前占用或意外副作用。

通常情况下,函数参数使用不可变类型(如整数、字符串)是安全的。但如果默认参数是可变类型(如列表或字典),每次调用函数时,其结果可能会因状态累积而发生变化。例如:

可变默认参数引发的副作用


def do_something(opt: print("参数 opt"), arg=[]) -> print("函数的返回值"): 
    print("do something runing") 
    print(f"{arg = }") 
    arg.append(0) 
 
if __name__ == "__main__": 
    do_something(opt=1) 
    do_something(opt=1) 

运行上述代码,结果如下:

观察发现,连续两次调用 do_something 函数且未传入 arg 参数时,arg 的值发生了累积变化。若忽视这一特性,极易引发难以排查的Bug。在 PyCharm 等IDE中,通常会对此类可变默认参数发出警告。

若需获取函数的类型提示和默认值,可以通过以下方式进行访问:

如何获取函数的类型提示与默认值


def do_something(opt: 1, arg=2) -> 3: 
    print("do something runing") 
    print(f"{arg = }") 
    arg.append(0) 
 
 
if __name__ == "__main__": 
    print(f"{do_something.__annotations__ = }") 
    print(f"{do_something.__defaults__ = }") 
 
#do_something.__annotations__ = {'opt': 1, 'return': 3} 
#do_something.__defaults__ = (2,) 

以上就是关于Python函数定义时执行机制的详细介绍。如需了解更多Python函数相关知识,建议查阅本站历史文章或继续浏览后续内容,感谢支持!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表