当前位置:首页>python>第06篇|Python 函数完全指南:从基础到 Lambda 表达式

第06篇|Python 函数完全指南:从基础到 Lambda 表达式

  • 2026-09-26 19:29:43
第06篇|Python 函数完全指南:从基础到 Lambda 表达式

前言

函数是代码的最小复用单位,也是理解装饰器、类方法、异步编程的基础。

Python 的函数整体和 JS 非常相似——都是一等公民,都可以作为参数传递,都支持匿名函数。但有几个 Python 特有的特性,比如 *args、**kwargs、关键字参数,是 JS 里没有直接对应物的,理解它们是迈向 Python 进阶的关键一步。

这篇文章覆盖:

  • 函数定义与调用(对比 JS function 和箭头函数)
  • 默认参数、关键字参数
  • *args 和 **kwargs
  • Lambda 表达式
  • 函数作为参数传递(高阶函数)

一、函数定义与调用

1.1 基本语法

# Python 函数定义def greet(name):    return f"你好,{name}!"result = greet("Alice")print(result)  # 你好,Alice!

对比 JS:

// JS 函数声明function greet(name) {  return `你好,${name}!`}// JS 箭头函数const greet = (name) => `你好,${name}!`

关键差异:

  • Python 用 def 关键字,JS 用 function
  • Python 用缩进定义函数体,JS 用 {}
  • Python 的 f-string f"..." 对应 JS 的模板字符串 `...`
  • Python 没有类似 JS 箭头函数的单行简写(但有 Lambda,后面讲)

1.2 多返回值

Python 函数可以直接返回多个值,这是 JS 没有的原生特性:

def get_min_max(numbers):    return min(numbers), max(numbers)low, high = get_min_max([3, 1, 4, 1, 5, 9, 2, 6])print(low, high)  # 1 9

本质上是返回一个元组,然后自动解包。JS 要实现类似效果需要返回数组或对象:

// JS 模拟多返回值const getMinMax = (arr) => ({ min: Math.min(...arr), max: Math.max(...arr) })const { min, max } = getMinMax([3, 1, 4, 1, 5, 9])

二、默认参数

def greet(name, greeting="你好"):    return f"{greeting},{name}!"print(greet("Alice"))            # 你好,Alice!print(greet("Bob", "早上好"))    # 早上好,Bob!

和 JS 完全一致:

const greet = (name, greeting = "你好") => `${greeting},${name}!`

⚠️ 经典踩坑:默认参数不要用可变对象

# ❌ 错误写法:默认参数是列表(可变对象),会被所有调用共享def add_item(item, lst=[]):    lst.append(item)    return lstprint(add_item("a"))  # ['a']print(add_item("b"))  # ['a', 'b']  ← 不是 ['b']!# ✅ 正确写法:用 None 作为默认值def add_item(item, lst=None):    if lst is None:        lst = []    lst.append(item)    return lst

这个坑 JS 不会踩,因为 JS 每次调用都会重新求值默认参数。


三、关键字参数

Python 调用函数时,可以用"参数名=值"的方式传参,这叫关键字参数:

def create_user(name, age, city="北京"):    return f"{name},{age}岁,来自{city}"# 位置参数(按顺序)print(create_user("Alice", 28))# 关键字参数(指定参数名,顺序可以随意)print(create_user(age=28, name="Alice"))print(create_user("Bob", city="上海", age=30))

关键字参数让函数调用更清晰,尤其是参数多时:

# 不用猜每个参数的含义send_email(    to="alice@example.com",    subject="通知",    body="你好,...",    cc="boss@example.com",    is_html=True)

JS 通常用对象参数解构来达到类似效果:

sendEmail({ to: "alice@example.com", subject: "通知", body: "你好..." })

四、*args:可变位置参数

当你不确定会传入多少个参数时,使用 *args:

def sum_all(*args):    print(args)       # 这是一个元组    return sum(args)print(sum_all(1, 2, 3))       # 6print(sum_all(1, 2, 3, 4, 5)) # 15

对比 JS 的 rest 参数:

const sumAll = (...args) => {  console.log(args)  // 这是一个数组  return args.reduce((a, b) => a + b, 0)}

语法几乎相同,区别是:

  • Python 里 *args 是元组(tuple,不可变)
  • JS 里 ...args 是数组(可变)

在函数调用时,* 也可以用来解包:

numbers = [1, 2, 3, 4, 5]# 解包列表作为位置参数传入print(sum_all(*numbers))  # 15# 对比 JS 的 spreadMath.max(...numbers)

五、**kwargs:可变关键字参数

**kwargs 接收任意数量的关键字参数,打包成字典:

def print_info(**kwargs):    print(kwargs)  # 这是一个字典    for key, value in kwargs.items():        print(f"{key}: {value}")print_info(name="Alice", age=28, city="北京")# {'name': 'Alice', 'age': 28, 'city': '北京'}# name: Alice# age: 28# city: 北京

完整参数顺序:

# 参数顺序规则:普通参数 → *args → 关键字参数 → **kwargsdef complex_func(a, b, *args, keyword_only, **kwargs):    print(f"a={a}, b={b}")    print(f"args={args}")    print(f"keyword_only={keyword_only}")    print(f"kwargs={kwargs}")complex_func(1, 2, 3, 4, keyword_only="必须用关键字", extra="额外参数")

实战场景:装饰器中几乎必用 *args, **kwargs:

def log_decorator(func):    def wrapper(*args, **kwargs):  # 接收任意参数        print(f"调用函数:{func.__name__}")        result = func(*args, **kwargs)  # 原样转发给原函数        return result    return wrapper

六、Lambda 表达式

Lambda 是 Python 的匿名函数,语法是:lambda 参数: 表达式

# 普通函数def square(x):    return x ** 2# 等价的 lambdasquare = lambda x: x ** 2print(square(5))  # 25

对比 JS 箭头函数:

const square = (x) => x ** 2

Lambda 的限制:只能写一个表达式,不能有多行逻辑。复杂逻辑还是要用 def。

Lambda 最常用的场景是作为 sort、map、filter 的参数:

students = [    {"name": "Alice", "score": 95},    {"name": "Bob", "score": 87},    {"name": "Charlie", "score": 92}]# 按 score 从高到低排序sorted_students = sorted(students, key=lambda s: s["score"], reverse=True)# [{'name': 'Alice', 'score': 95}, {'name': 'Charlie', 'score': 92}, ...]

对比 JS:

students.sort((a, b) => b.score - a.score)

七、高阶函数:map、filter、sorted

Python 内置了几个经典高阶函数,前端开发者一定眼熟:

7.1 map()

numbers = [1, 2, 3, 4, 5]# 每个数平方squared = list(map(lambda x: x ** 2, numbers))print(squared)  # [1, 4, 9, 16, 25]

对比 JS:

const squared = numbers.map(x => x ** 2)

💡 Python 的 map() 返回的是迭代器,需要用 list() 转换。不过大多数情况下,Python 推荐用列表推导式代替 map(),更 Pythonic:

squared = [x ** 2 for x in numbers]

7.2 filter()

numbers = [1, 2, 3, 4, 5, 6, 7, 8]# 过滤出偶数evens = list(filter(lambda x: x % 2 == 0, numbers))print(evens)  # [2, 4, 6, 8]# 推荐写法(列表推导式)evens = [x for x in numbers if x % 2 == 0]

7.3 函数作为参数传递

def apply_twice(func, value):    return func(func(value))def double(x):    return x * 2print(apply_twice(double, 3))  # 12(3 → 6 → 12)

八、类型提示(Type Hints)

Python 3.5+ 支持为函数参数和返回值添加类型提示,提升代码可读性,也方便 IDE 做智能提示:

def add(a: int, b: int) -> int:    return a + bdef greet(name: str, times: int = 1) -> str:    return f"你好,{name}!" * timesdef process(items: list[str]) -> dict[str, int]:    return {item: len(item) for item in items}

类型提示在运行时不做强制检查(Python 是动态语言),但 VS Code 等编辑器会根据类型提示提供自动补全和错误提醒,写大型项目时强烈建议加上。


小结

特性
Python 写法
JS 对应
函数定义
def func(x):function func(x) {}
默认参数
def f(x, y=0):const f = (x, y = 0) =>
可变位置参数
*args
 → 元组
...args
 → 数组
可变关键字参数
**kwargs
 → 字典
无直接对应
匿名函数
lambda x: x*2x => x*2
多返回值
return a, b
返回数组/对象

记住这几条:

  1. 默认参数不要用可变对象(列表/字典),用 None 代替
  2. *args 收到的是元组,**kwargs 收到的是字典
  3. Lambda 只适合简单表达式,复杂逻辑还是用 def
  4. 大多数情况下,列表推导式比 map()/filter() 更 Pythonic

下篇预告

第 07 篇:Python 文件操作 + JSON 处理:前后端数据交换全攻略

下一篇我们进入实战场景:用 Python 读写文件、处理 JSON 数据。前端每天和 JSON 打交道,后端操作文件是基本功,这两个技能合并一篇讲清楚。


最新文章

随机文章