核心要点

  • 理解 def、参数传递、返回值与作用域(LEGB)

  • 能解释默认参数陷阱(可变默认值)

  • 知道函数是一等公民、可作为参数/返回值

标准回答

定义与调用def name(params): ... return x。调用时创建栈帧,形参获得实参引用的绑定(传对象引用,非 C 式传值/传址)。

作用域 LEGB:Local → Enclosing → Global → Built-in。内层可读外层,赋值则创建局部变量除非 nonlocal/global 声明。

默认参数:在定义时求值一次——def f(a, lst=[])lst 是共享可变对象,应写 lst=None 再在函数内 lst = lst or []

一等公民:函数可赋值、作参数、作返回值,支撑装饰器、回调、函数式风格。ML 训练中 loss_fnoptimizer.step 皆依赖此机制。

常见误区

⚠️ 常见踩坑

把「传引用」说成「传指针」;默认参数用可变对象 []/{};混淆 returnprint

追问

追问 1Python 是传值还是传引用?

准确说法是 call by object reference(传对象引用):形参与实参指向同一对象;重新绑定形参(如 x = x + 1 对不可变类型)不影响外部变量,但对可变对象原地修改(如 lst.append)会影响调用方。

追问 2闭包是什么?常见用途?

内层函数引用外层函数的变量,外层返回后内层仍持有该变量——形成闭包。用途:工厂函数、装饰器、携带状态的回调。注意循环中 lambda 捕获变量的经典坑。

追问 3*args 和 **kwargs 在函数签名里如何配合普通参数?

题库专题:Python 中 *args 和 **kwargs 是什么?

签名顺序固定:普通位置参数 → *args → keyword-only 参数 → kwargs,如 def f(a, b=1, *args, c, kwargs)*args 之后的形参都是仅限关键字传参;只想强制 keyword-only 而不收集多余位置参数时用裸 *,如 def f(a, *, c)

题库延伸:与本追问相关的专题题 → Python 中 *args 和 kwargs 是什么?

延伸学习

与本题相关的知识库文章、术语、工具与行业资讯。