← 返回题目列表

Python 的高阶函数和一等函数是什么?函数能当参数和返回值吗?

高频 简单 第 1 / 21 题 更新于 2026/07/31
Python高阶函数一等函数函数式

简化版

Python 的函数是「一等公民(first-class citizen)」——函数和普通值(数字、字符串)地位相同,可以赋值给变量、作为参数传给别的函数、作为返回值返回、存进容器;而「高阶函数(higher-order function)」就是「接收函数作为参数,或返回函数」的函数。「一等函数」是能力(函数能被当值处理),「高阶函数」是用法(利用这个能力的函数)。例子:① 函数作参数——sorted(data, key=len)(把 len 函数传进去)、map(str, nums);② 函数作返回值——def make_adder(n): def adder(x): return x + n; return adder(返回一个函数,闭包);③ 赋值/存容器——f = printops = {'+': add, '-': sub}常见高阶函数mapfiltersorted(key)、max/min(key)、装饰器(接收并返回函数)、functools.reduce/partial为什么有用:让代码更抽象、可复用、可组合——把「行为」当参数传,写出通用的框架(如排序算法通用、具体比较规则由 key 决定)。核心记忆:一等函数=函数能当值(赋值/传参/返回/存容器),高阶函数=接收或返回函数的函数(map/sorted/装饰器);让行为可传递、代码可复用组合。

详细版

一等函数的四种表现

表现例子
赋值给变量f = len
作为参数传递sorted(data, key=len)
作为返回值return inner_func(闭包/装饰器)
存进容器funcs = [str, int, float]
# ① 赋值给变量(函数是对象)
f = len
print(f("hello"))           # 5(f 就是 len)
funcs = [str.upper, str.lower, str.strip]

# ② 作为参数传递(高阶函数的"接收函数")
def apply(func, value):     # apply 是高阶函数
    return func(value)
apply(len, "hello")         # 5
apply(str.upper, "hi")      # "HI"

sorted([-3, 1, -2], key=abs)    # [1, -2, -3](把 abs 传进去)
max(["a", "bbb", "cc"], key=len)  # "bbb"(按长度)

# ③ 作为返回值(高阶函数的"返回函数")
def make_multiplier(factor):    # 返回一个函数
    def multiplier(x):
        return x * factor       # 闭包捕获 factor
    return multiplier
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5), triple(5))     # 10 15

# ④ 存进容器(字典分派)
operations = {
    "add": lambda a, b: a + b,
    "sub": lambda a, b: a - b,
}
print(operations["add"](3, 4))  # 7(用字典代替 if-elif)

# 装饰器:既接收函数又返回函数(典型高阶函数)
def timer(func):                # 接收函数
    def wrapper(*args, **kw):
        # ...计时...
        return func(*args, **kw)
    return wrapper              # 返回函数

# 常见高阶函数:map/filter/sorted/reduce/partial/装饰器
list(map(str.upper, ["a", "b"]))       # ['A', 'B']
list(filter(str.isdigit, "a1b2"))      # ['1', '2']

⚠️ 两个概念要分清:「一等函数(first-class functions)」是 Python 的一个「特性」——函数被当作「一等公民」,和整数、字符串一样是普通对象,可以赋值、传递、返回、存储;「高阶函数(higher-order function)」是一类「函数」——它接收函数作为参数,或者返回函数(或两者都有)。前者是「能力/前提」,后者是「利用这个能力的用法」;正因为 Python 有一等函数,才能写高阶函数。这个能力的价值在于「把行为(做什么)当作数据来传递和组合」:sorted 是通用的排序算法、具体「按什么排」由你传的 key 函数决定(把「比较规则」这个行为参数化);map/filter 把「对每个元素做什么」参数化;装饰器把「包装/增强函数」这个行为抽象出来。这让代码更抽象、更可复用(一个通用框架 + 可替换的行为)、更可组合(函数返回函数、层层组合)。日常写 Python 时你其实一直在用一等函数——传 key、用 map、写装饰器、把回调函数传给框架,都是。理解这个概念能帮你写出更简洁、更灵活的代码(用高阶函数代替重复的样板、用字典分派代替长 if-elif)。

完整版教学

一、一等函数:函数是对象

先理解一等函数的含义:

"一等公民(first-class citizen)":
  某种东西能被"当作普通值"对待
  → 能赋值、传参、返回、存储

Python 函数是一等公民(一等函数):
  函数和数字、字符串一样是"对象"
  → 拥有普通值的所有待遇

四种表现(能像值一样):
  ① 赋值给变量:f = some_function
  ② 作参数传递:g(some_function)
  ③ 作返回值:return some_function
  ④ 存进容器:[f1, f2]、{key: func}

对比不是一等函数的语言:
  有些语言函数不是一等的(早期 Java 只能传对象、用接口绕)
  → Python 函数天生一等,直接传函数

为什么函数能这样:
  函数是对象(有类型 function、有属性、可传递)
  def f(): ... 创建一个函数对象,f 是指向它的名字
  → f 可以像任何变量一样被处理

一等函数是很多特性的基础:
  高阶函数、装饰器、回调、闭包、函数式编程
  → 都建立在"函数能当值"之上

所以一等函数=函数能当普通值(赋值/传参/返回/存容器),因为函数是对象

「一等公民(first-class citizen)」:某种东西能被「当作普通值」对待(能赋值、传参、返回、存储)。Python 函数是一等公民(一等函数):函数和数字、字符串一样是「对象」、拥有普通值的所有待遇。四种表现(能像值一样)① 赋值给变量、② 作参数传递、③ 作返回值、④ 存进容器对比不是一等函数的语言:有些语言函数不是一等的(早期 Java 只能传对象、用接口绕)、Python 函数天生一等直接传函数。为什么函数能这样:函数是对象(有类型 function、有属性、可传递)、def f() 创建函数对象、f 是指向它的名字(可像任何变量处理)。一等函数是很多特性的基础:高阶函数、装饰器、回调、闭包、函数式编程都建立在「函数能当值」之上。理解「一等函数=函数能当普通值(赋值/传参/返回/存容器);因为函数是对象(有类型有属性可传递);是高阶函数/装饰器/回调/闭包的基础」,就理解了一等函数。

二、高阶函数:接收或返回函数

理解高阶函数的定义:

高阶函数(higher-order function):
  ① 接收函数作为参数,或
  ② 返回函数,或
  ③ 两者都有

接收函数作参数:
  def apply_twice(func, x):
      return func(func(x))    # func 是传进来的函数
  apply_twice(lambda x: x+1, 5)  # 7

  内置例子:
  sorted(data, key=func)      # key 是函数
  map(func, iterable)
  filter(func, iterable)
  max(data, key=func)

返回函数:
  def make_adder(n):
      def adder(x):
          return x + n         # 闭包,捕获 n
      return adder             # 返回函数
  add5 = make_adder(5)
  add5(10)  # 15

  → "函数工厂":根据参数生成不同的函数

两者都有(装饰器):
  def deco(func):             # 接收函数
      def wrapper(*a):
          return func(*a)
      return wrapper           # 返回函数
  → 装饰器是典型高阶函数

一等函数 vs 高阶函数(区分):
  一等函数:特性(函数能当值)
  高阶函数:用法(接收/返回函数的函数)
  → 有一等函数,才能写高阶函数

所以高阶函数=接收函数或返回函数的函数(sorted/map/装饰器/函数工厂)

高阶函数(higher-order function)① 接收函数作为参数、或 ② 返回函数、或 ③ 两者都有接收函数作参数def apply_twice(func, x): return func(func(x));内置例子 sorted(data, key=func)map(func, it)filtermax(data, key=func)返回函数def make_adder(n): def adder(x): return x + n; return adder(「函数工厂」:根据参数生成不同的函数)。两者都有(装饰器)def deco(func): def wrapper(*a): return func(*a); return wrapper(装饰器是典型高阶函数)。一等函数 vs 高阶函数(区分):一等函数是特性(函数能当值)、高阶函数是用法(接收/返回函数的函数)——有一等函数才能写高阶函数。理解「高阶函数=接收函数(sorted/map 的 key)或返回函数(函数工厂 make_adder)或两者(装饰器);一等函数是特性、高阶函数是用法;有一等函数才能写高阶函数」,就掌握了高阶函数。

三、函数作参数——行为参数化

理解「把行为当参数传」的价值:

函数作参数 = "行为参数化"(把'做什么'当参数):

例子:通用的排序、可换比较规则
  # sorted 是通用算法、key 决定"按什么排"
  sorted(people, key=lambda p: p.age)      # 按年龄
  sorted(people, key=lambda p: p.name)     # 按名字
  sorted(words, key=len)                   # 按长度
  → 一个 sorted,无数种排序(行为由 key 传入)

例子:回调(框架调用你的函数):
  button.on_click(my_handler)   # 传入回调函数
  threading.Thread(target=my_task)
  → 框架在合适时机调用你传的函数

例子:策略(把算法当参数):
  def process(data, transform):
      return [transform(x) for x in data]
  process(nums, lambda x: x*2)
  process(nums, str)
  → 处理流程固定、具体变换可换

好处:
  ① 复用——通用框架 + 可替换行为(不用为每种情况写一个函数)
  ② 灵活——运行时决定用哪个行为
  ③ 解耦——框架不关心具体行为、只管调用

对比不用高阶函数(重复):
  # 不用:为每种排序写一个函数
  def sort_by_age(people): ...
  def sort_by_name(people): ...
  # 用:一个 sorted + 不同 key
  sorted(people, key=...)

所以函数作参数=行为参数化(把'做什么'当参数),通用框架+可换行为,复用/灵活/解耦

函数作参数 = 「行为参数化」(把’做什么’当参数)例子:通用的排序、可换比较规则sorted 是通用算法、key 决定按什么排,sorted(people, key=lambda p: p.age) 一个 sorted 无数种排序);例子:回调button.on_click(my_handler) 传入回调、框架在合适时机调用);例子:策略def process(data, transform): return [transform(x) for x in data] 处理流程固定、具体变换可换)。好处① 复用(通用框架+可替换行为、不用为每种情况写一个函数)、② 灵活(运行时决定用哪个行为)、③ 解耦(框架不关心具体行为只管调用)对比不用高阶函数(重复):不用要为每种排序写一个函数、用一个 sorted + 不同 key。理解「函数作参数=行为参数化(把做什么当参数);sorted 通用+key 换排序、回调、策略;好处复用(框架+可换行为)/灵活/解耦;代替为每种情况写一个函数」,就掌握了行为参数化。

四、函数作返回值——函数工厂与闭包

理解「返回函数」的应用:

返回函数 = "函数工厂"(根据参数生成定制函数):

例子:生成定制函数
  def power_of(exp):
      def f(base):
          return base ** exp    # 捕获 exp(闭包)
      return f
  square = power_of(2)   # 生成"平方"函数
  cube = power_of(3)     # 生成"立方"函数
  square(5)  # 25

闭包:返回的函数"记住"了外层变量
  make_adder(5) 返回的 adder 记住了 n=5
  → 闭包捕获外层作用域的变量(见闭包专题)

例子:配置化的处理器
  def make_validator(min_len):
      def validate(s):
          return len(s) >= min_len
      return validate
  check = make_validator(8)
  check("password")  # True/False

例子:装饰器(返回包装后的函数)
  def log(func):
      def wrapper(*a, **k):
          print(f"调用 {func.__name__}")
          return func(*a, **k)
      return wrapper
  → 返回一个"增强版"的函数

返回函数的价值:
  ① 定制——根据参数生成不同行为的函数
  ② 延迟——先配置、后调用(生成时定参数、调用时执行)
  ③ 封装状态——闭包记住配置(比全局变量干净)

vs functools.partial:
  partial 也能"固定参数生成新函数"(但只固定参数)
  返回函数更灵活(能加逻辑、改行为)

所以返回函数=函数工厂(根据参数生成定制函数),配合闭包记住配置,装饰器是典型

返回函数 = 「函数工厂」(根据参数生成定制函数)例子:生成定制函数def power_of(exp): def f(base): return base ** exp; return fsquare = power_of(2) 生成平方函数);闭包:返回的函数「记住」了外层变量(make_adder(5) 返回的 adder 记住 n=5、闭包捕获外层作用域变量);例子:配置化的处理器make_validator(8) 生成检查长度≥8 的函数);例子:装饰器(返回增强版的函数)。返回函数的价值① 定制(根据参数生成不同行为的函数)、② 延迟(先配置后调用)、③ 封装状态(闭包记住配置、比全局变量干净)vs functools.partial:partial 也能固定参数生成新函数(但只固定参数)、返回函数更灵活(能加逻辑改行为)。理解「返回函数=函数工厂(根据参数生成定制函数如 power_of);配合闭包记住配置;装饰器是典型;价值定制/延迟/封装状态;比 partial 灵活(能加逻辑)」,就掌握了函数工厂。

五、函数存容器——字典分派

理解「函数存进容器」的实用模式:

函数存进容器:字典/列表存函数,动态选择/批量应用

字典分派(代替 if-elif 链):
  # 不用高阶函数(长 if-elif):
  def calc(op, a, b):
      if op == "+": return a + b
      elif op == "-": return a - b
      elif op == "*": return a * b
      ...
  # 用字典存函数(清晰、可扩展):
  import operator
  OPS = {"+": operator.add, "-": operator.sub, "*": operator.mul}
  def calc(op, a, b):
      return OPS[op](a, b)     # 查表 + 调用
  → 加新操作只需往字典加一项,不改函数

列表存函数(管道/批量应用):
  transforms = [str.strip, str.lower, remove_punct]
  def clean(text):
      for f in transforms:
          text = f(text)
      return text
  → 处理步骤存列表,顺序应用(可配置管道)

回调注册表:
  handlers = {}
  def register(event, func):
      handlers[event] = func
  → 事件 → 处理函数的映射

好处:
  ① 用查表代替 if-elif(清晰、O(1)、可扩展)
  ② 处理流程可配置(列表/字典存步骤)
  ③ 动态注册/替换行为

配合 singledispatch/策略模式:
  字典分派是"策略模式"的轻量实现
  → 用函数字典代替一堆 if 或子类

所以函数存容器:字典分派(代替 if-elif)、列表管道、回调注册表;查表代替分支、可配置

函数存进容器:字典/列表存函数,动态选择/批量应用字典分派(代替 if-elif 链):不用高阶函数是长 if-elif、用字典 OPS = {"+": operator.add, ...} + OPS[op](a, b)(查表+调用、加新操作只需加一项不改函数)。列表存函数(管道/批量应用)transforms = [str.strip, str.lower, ...] + for f in transforms: text = f(text)(处理步骤存列表、顺序应用、可配置管道)。回调注册表handlers = {} + register(event, func)(事件→处理函数的映射)。好处① 用查表代替 if-elif(清晰、O(1)、可扩展)、② 处理流程可配置、③ 动态注册/替换行为配合 singledispatch/策略模式:字典分派是「策略模式」的轻量实现(用函数字典代替一堆 if 或子类)。理解「函数存容器:字典分派(OPSop代替 if-elif、加操作只加一项)、列表管道(顺序应用)、回调注册表;查表代替分支 O(1)可扩展、流程可配置;是策略模式轻量实现」,就掌握了字典分派。

六、总结与实践

总结一等函数和高阶函数:

一等函数(特性):
  函数能当普通值:赋值、传参、返回、存容器
  → 因为函数是对象

高阶函数(用法):
  接收函数作参数,或返回函数
  → 建立在一等函数之上

三大应用:
  ① 函数作参数(行为参数化):
     sorted(key=)、map、filter、回调、策略
  ② 函数作返回值(函数工厂):
     make_adder、装饰器、闭包记住配置
  ③ 函数存容器(字典分派):
     OPS[op](a,b) 代替 if-elif、管道、注册表

常见高阶函数:
  map、filter、sorted/max/min(key)、reduce、
  partial、装饰器

价值:
  ① 复用——通用框架 + 可替换行为
  ② 抽象——把"行为"当数据处理
  ③ 可组合——函数返回函数、层层组合
  ④ 简洁——代替重复样板、代替长 if-elif

实践建议:
  ① 排序/映射用 key(传函数)
  ② 重复逻辑抽成高阶函数(框架 + 行为参数)
  ③ 长 if-elif 分派 → 函数字典
  ④ 需要定制函数 → 函数工厂(返回函数)

核心总结:
  一等函数=函数能当值、高阶函数=接收/返回函数
  应用:行为参数化、函数工厂、字典分派
  让代码复用、抽象、可组合

所以一等函数=函数能当值、高阶函数=接收/返回函数,应用行为参数化/函数工厂/字典分派

一等函数(特性):函数能当普通值(赋值、传参、返回、存容器、因为函数是对象)。高阶函数(用法):接收函数作参数或返回函数(建立在一等函数之上)。三大应用① 函数作参数(行为参数化)(sorted key、map、filter、回调、策略)、② 函数作返回值(函数工厂)(make_adder、装饰器、闭包记住配置)、③ 函数存容器(字典分派)OPS[op](a,b) 代替 if-elif、管道、注册表)。常见高阶函数:map、filter、sorted/max/min(key)、reduce、partial、装饰器。价值:复用、抽象、可组合、简洁。理解「一等函数=函数能当值、高阶函数=接收/返回函数;应用行为参数化(sorted key)/函数工厂(返回函数)/字典分派(代替 if-elif);常见 map/filter/sorted/装饰器;让代码复用抽象可组合简洁」,就掌握了总结与实践。

记忆钩子:「Python 的函数是『一等公民(first-class citizen)』——函数和普通值(数字/字符串)地位相同,可以①赋值给变量(f=len)②作为参数传给别的函数(sorted(data,key=len))③作为返回值返回(def make_adder(n):def adder(x):return x+n;return adder)④存进容器(ops={’+‘:add,’-‘:sub});★两个概念要分清:『一等函数(first-class functions)』是特性(函数能被当值处理)、『高阶函数(higher-order function)』是用法(接收函数作参数、或返回函数的函数)——有一等函数才能写高阶函数;★三大应用:①函数作参数=『行为参数化』(把做什么当参数,sorted 是通用算法、key 决定按什么排,一个 sorted 无数种排序;回调;策略)②函数作返回值=『函数工厂』(根据参数生成定制函数,配合闭包记住配置,装饰器是典型)③函数存容器=『字典分派』(OPSop查表调用代替一长串 if-elif、加操作只需加一项,是策略模式的轻量实现);常见高阶函数 map/filter/sorted-max-min 的 key/reduce/partial/装饰器;价值:通用框架+可替换行为→代码更复用、抽象、可组合、简洁(代替重复样板和长 if-elif)」

七、常见误区与追问

  • 误区:一等函数和高阶函数是一回事。 不同——「一等函数(first-class functions)」是 Python 的一个「特性」,指函数被当作一等公民、和普通值一样可以赋值/传参/返回/存储;「高阶函数(higher-order function)」是一类「函数」,指接收函数作参数或返回函数的函数;前者是「能力/前提」、后者是「利用这个能力的用法」;正因为 Python 的函数是一等的,才能写出 sorted(接收 key 函数)、装饰器(返回函数)这样的高阶函数。
  • 误区:函数不能像变量一样赋值和传递。 能——Python 函数是对象,可以 f = len(赋值,之后 f("hi") 就是调 len)、sorted(data, key=len)(作参数传递)、return inner(作返回值)、[str, int](存进列表)、{"add": add_func}(存进字典);这是很多 Python 惯用法的基础,比如给 sorted/map 传函数、写回调、用函数字典代替 if-elif。
  • 误区:只有 map、filter、reduce 这些内置才是高阶函数。 不是——高阶函数是「接收函数或返回函数」的任何函数:内置的 sorted/max/min(接收 key 函数)、map/filter(接收函数)、functools.partial(返回可调用对象)都是;你自己写的「接收回调的函数」「返回函数的函数工厂」「装饰器」也都是高阶函数;甚至给框架传回调(thread = Thread(target=my_func))、注册事件处理器都是在用高阶函数的思想。
  • 误区:把函数存进字典没什么用。 很有用——「函数字典分派」是代替一长串 if-elif 的经典模式:OPS = {"+": operator.add, "-": operator.sub} 然后 OPS[op](a, b),比 if op == "+": ... elif op == "-": ... 更清晰、查找是 O(1)、而且扩展时只需往字典加一项(不用改函数体、符合开闭原则);它本质是「策略模式」的轻量实现;类似地把函数存进列表可以做「处理管道」(按顺序应用一串变换函数)。
  • 追问:什么是「一等函数」,Python 函数作为一等公民有哪些具体表现? 「一等公民」指某种东西能被当作普通值来对待——能赋值、能作参数、能作返回值、能存进数据结构;Python 的函数是一等公民(所以叫「一等函数」),因为函数本身就是对象(有类型 function、有属性、能被引用传递);具体四种表现:① 赋值给变量(f = some_func,f 就指向那个函数);② 作为参数传递给其他函数(sorted(data, key=len) 把 len 传进去);③ 作为返回值从函数返回(return inner_func,常见于闭包和装饰器);④ 存进容器(列表 [f1, f2]、字典 {"op": func});正是这个特性,使得高阶函数、装饰器、回调、闭包、函数式编程在 Python 里都成为可能。
  • 追问:高阶函数有什么实际价值,能举例说明吗? 核心价值是「把行为(做什么)当作数据来传递和组合」,带来复用、灵活、解耦:① 行为参数化——sorted 是通用排序算法、具体「按什么排」由你传的 key 函数决定,一个 sorted 就能实现按年龄、按名字、按长度等无数种排序(sorted(people, key=lambda p: p.age)),不用为每种排序写一个函数;② 函数工厂——def make_multiplier(n): def f(x): return x*n; return f 根据参数生成定制的函数(double = make_multiplier(2)),配合闭包记住配置;③ 回调/框架集成——把你的函数传给框架、框架在合适时机调用(事件处理、线程 target);④ 字典分派——用函数字典代替长 if-elif;这些都让代码更抽象(通用框架+可替换行为)、更可复用、更可组合。
  • 追问:函数作为返回值(函数工厂)和 functools.partial 有什么区别,什么时候用哪个? 两者都能「生成新的可调用对象」,但灵活度不同:functools.partial(func, 已知参数) 只能「固定原函数的部分参数」、不能改变逻辑(它就是把 func 和预设参数打包、调用时补上剩余参数转发给 func);而「返回函数的函数工厂」可以在返回的内层函数里写任意逻辑——不只是固定参数,还能加计算、改行为、组合多个调用、用闭包维护状态(def make_validator(min_len): def v(s): return len(s) >= min_len; return v);选择:如果只是「固定几个参数生成专用函数」,用 partial(更简洁、可内省、可 pickle);如果需要「返回的函数有自定义逻辑或状态」,用函数工厂(返回内层函数);装饰器就是函数工厂的典型——它返回一个「包装了原函数、加了额外行为」的新函数。

八、加强记忆

Python 的函数是「一等公民(first-class citizen)」——函数和普通值(数字/字符串)地位相同,可以 ① 赋值给变量f = len)、② 作为参数传给别的函数sorted(data, key=len))、③ 作为返回值返回def make_adder(n): def adder(x): return x + n; return adder)、④ 存进容器ops = {'+': add, '-': sub})。两个概念要分清:「一等函数(first-class functions)」是特性(函数能被当值处理)、「高阶函数(higher-order function)」是用法(接收函数作参数、或返回函数的函数)——有一等函数才能写高阶函数。三大应用① 函数作参数 = 「行为参数化」(把’做什么’当参数,sorted 是通用算法、key 决定按什么排,一个 sorted 无数种排序;回调;策略)、② 函数作返回值 = 「函数工厂」(根据参数生成定制函数、配合闭包记住配置,装饰器是典型)、③ 函数存容器 = 「字典分派」OPS[op](a,b) 查表调用代替一长串 if-elif、加操作只需加一项,是策略模式的轻量实现)。常见高阶函数:map、filter、sorted/max/min 的 key、reduce、partial、装饰器。价值:通用框架 + 可替换行为 → 代码更复用、抽象、可组合、简洁。一句话「一等函数=函数能当普通值(赋值/传参/返回/存容器)、高阶函数=接收或返回函数的函数;应用行为参数化(sorted 的 key)、函数工厂(返回定制函数)、字典分派(代替 if-elif);让代码复用、抽象、可组合」。