学径 LearnPath

编程语言基础 / Wiki

函数

把一组步骤封进一个名字,需要时再调用;参数接收材料,return 把结果交回给调用者。

它是什么

函数 把一段过程打包起来。名字表示它能做什么,括号里的参数接收材料,return 把结果交回给调用者。外面的人不必每次重写那一串步骤,这就是对过程的 抽象:思考停在「给定这些输入,应得到什么」,而不是同时消化所有中间运算。

python
def solve(a, b, c, d):
    if a == c:
        return None
    return (d - b) / (a - c)

调用时写 solve(2, 3, 0, 0)。定义不会自己跑,要点名加上括号。没有 return 时,得到的是 None。只 print 不 return,屏幕上可以有字,调用方却接不到可继续使用的值。

名字从哪来

function 来自数学:一台「放进自变量、得到因变量」的机器。f(x)=x+1f(x) = x + 1 放进 3 得到 4。编程沿用这个词,但步骤可以比一个代数式长得多,也可以包含 选择 与 循环。def 是 define 的缩写。return 是「送回」。Python 还自带许多已经定义好的函数,例如 print、len、abs。

数学函数通常对每个合法输入给出唯一输出。程序里的函数还可以有副作用,例如打印或改写外部状态。能否把副作用关在函数内部、让返回值承担主要约定,决定了这个抽象是否容易被检验。

它怎么工作

调用时,实参按位置(或按名字)传给形参。函数内部可以有自己的 变量,外面通常拿不到。return 一执行,函数立刻结束,后面的句子不会再跑。参数个数或顺序对不上会报 TypeError,或算对了位置却用错了系数——后者更危险,因为它能运行。

函数可以调用别的函数,也可以调用自己,后者称为 递归。把「一件事算完就结束」写成函数,比把所有步骤摊在主流程里更容易指出边界:分母何时为零、列表何时为空,应当出现在这个名字的约定里,而不是散落在调用现场。

生活里在哪里

食谱:材料不同,步骤同一份。实验室的标准操作流程:别人只关心「送样、出结果」,不必每次重写步骤。计算器的某个功能键。这些类比里,真正重要的是接口——传入什么、传出什么、保证什么——而不是厨房或仪器内部有多少齿轮。日后用 对话式编程 时,人要能说出函数应当完成什么,才能判断草稿是否在为问题建模,而不是只看见它打印了一串看起来合理的字。

和相近概念的差别

函数打包步骤。循环重复步骤。可以在函数里写循环。类 把数据和针对这些数据的函数绑在一起。单独的函数更轻,适合一次性计算。模块 是许多函数(和类)的仓库。import 把别人写好的函数借来用。

注释可以说明意图,但不能代替函数。细节仍摊在主流程里时,读的人还是要同时消化所有步骤。见 注释。

常见误会

误会 1:只定义不调用,以为会自己执行。

定义是说明书。要产生结果,还得调用。

误会 2:看见 print 的输出,就等于拿到了返回值。

外面用变量去接一个只 print 的函数,常常接到 None。

误会 3:参数个数或顺序可以随便写。

对不上会报错,或更糟:能运行,却把系数用在错误的位置上。能运行不等于模型正确。

想知道更多

  • 书:艾伦·唐尼《像计算机科学家一样思考Python(第2版)》
  • 书:布鲁克希尔《计算机科学概论》
  • 书:埃里克·马瑟斯《Python编程:从入门到实践(第3版)》

未登录时不会保存学习进度