源本科技 | 码上会

Python 函数入门

2026/01/16
7
0

学习目标

  • 理解 Python 函数的基本定义与调用方式

  • 掌握函数参数的多种类型及其使用场景

  • 了解嵌套函数、匿名函数(lambda)和递归函数的特性

  • 明确 Python 中参数传递机制的本质(对象引用传递)

  • 能够编写结构清晰、可复用的函数代码


什么是函数

在 Python 中,函数是一段执行特定任务的代码块。通过将常用或重复的逻辑封装成函数,我们可以避免重复编写相同代码,只需在需要时调用该函数即可,极大提升了代码的可读性与可维护性。


定义函数

使用 def 关键字定义函数。函数可以接受输入(称为参数),也可以不接受任何参数。

def greet():
    print("欢迎来到 CodeLab")

上述代码定义了一个名为 greet 的函数,调用时会输出欢迎信息。


调用函数

定义函数后,通过函数名加括号的方式进行调用:

def greet():
    print("欢迎来到 CodeLab")

greet()  # 调用函数

输出:

欢迎来到 CodeLab

函数参数与返回值

函数可以接收参数,并通过 return 语句返回结果。

def even_odd(x):
    if x % 2 == 0:
        return "偶数"
    else:
        return "奇数"

print(even_odd(16))  # 输出:偶数
print(even_odd(7))   # 输出:奇数

说明return 语句用于将结果传回调用处。若无 return,函数默认返回 None


函数参数的类型

Python 支持多种参数传递方式,灵活应对不同需求。

1. 默认参数

当调用函数时未提供某个参数的值,该参数将使用预先设定的默认值。

def introduce(name, age=25):
    print(f"姓名: {name}")
    print(f"年龄: {age}")

introduce("李明")        # 使用默认年龄
introduce("王芳", 30)   # 指定年龄

输出:

姓名: 李明
年龄: 25
姓名: 王芳
年龄: 30

2. 关键字参数

调用函数时通过参数名显式指定值,顺序无关。

def describe(first_name, last_name):
    print(first_name, last_name)

describe(first_name="张", last_name="伟")
describe(last_name="伟", first_name="张")  # 顺序颠倒仍正确

输出:

张 伟
张 伟

3. 位置参数

参数按位置依次赋值,顺序必须严格匹配。

def say_hello(name, greeting):
    print(f"{greeting}, 我是 {name}!")

say_hello("小陈", "你好")      # 正确
say_hello("你好", "小陈")      # 逻辑错误!

输出:

你好, 我是 小陈!
小陈, 我是 你好!

注意:位置参数顺序错误会导致语义混乱。


4. 可变数量参数

当参数数量不确定时,可使用 *args(非关键字参数)和 **kwargs(关键字参数)。

def log_args(*args, **kwargs):
    print("非关键字参数 (*args):")
    for item in args:
        print(item)
    
    print("\n关键字参数 (**kwargs):")
    for key, value in kwargs.items():
        print(f"{key} = {value}")

log_args('开始', '处理', action='登录', user='admin')

输出:

非关键字参数 (*args):
开始
处理

关键字参数 (**kwargs):
action = 登录
user = admin
  • *args 接收任意多个位置参数,打包为元组

  • **kwargs 接收任意多个关键字参数,打包为字典


嵌套函数(内部函数)

函数可以在另一个函数内部定义,称为嵌套函数。内部函数可以访问外部函数的变量。

def outer():
    message = "我热爱编程"
    def inner():
        print(message)
    inner()

outer()

输出:

我热爱编程

这种结构常用于封装私有逻辑或实现闭包(closure)。


匿名函数(Lambda)

使用 lambda 关键字创建匿名函数——没有名字的简短函数,通常用于简单操作。

# 普通函数
def cube(x):
    return x ** 3

# 匿名函数
cube_lambda = lambda x: x ** 3

print(cube(5))         # 125
print(cube_lambda(5))  # 125

适用场景:作为高阶函数(如 map, filter, sorted)的参数。


返回语句(return)

return 用于结束函数并返回结果。可返回单个值、多个值(自动打包为元组)或 None

def get_stats(a, b):
    return a + b, a * b  # 返回两个值

sum_val, product = get_stats(3, 4)
print("和:", sum_val)      # 和: 7
print("积:", product)     # 积: 12

参数传递机制

引用传递还是值传递?

Python 中所有变量都是对象的引用。函数参数传递的是对象的引用,行为取决于对象是否可变:

  • 不可变对象(如 int, str, tuple):函数内修改不会影响原变量

  • 可变对象(如 list, dict):函数内修改会影响原对象

# 修改列表(可变)
def modify_list(lst):
    lst[0] = 999

my_list = [1, 2, 3]
modify_list(my_list)
print(my_list)  # [999, 2, 3]

# 修改整数(不可变)
def modify_int(x):
    x = 888

num = 100
modify_int(num)
print(num)      # 100(未改变)

技术上称为 “传对象引用”


递归函数

函数调用自身称为递归。必须包含终止条件,否则会无限循环。

def factorial(n):
    if n == 0:          # 基础情况
        return 1
    return n * factorial(n - 1)  # 递归调用

print(factorial(4))  # 24

典型应用:阶乘、斐波那契数列、树遍历等分治问题。


重点总结

  • 函数通过 def 定义,用 函数名() 调用

  • 参数类型包括:默认参数、关键字参数、位置参数、*args / **kwargs

  • 内部函数可访问外层作用域变量

  • lambda 用于创建简洁的匿名函数

  • return 返回结果,支持多值返回

  • Python 采用“传对象引用”机制,可变对象在函数中可被修改

  • 递归需设置明确的终止条件,防止栈溢出


思考题

  1. 为什么在使用位置参数时,参数顺序非常重要?能否举一个因顺序错误导致程序逻辑出错的例子?

  2. 在什么情况下你会选择使用 *args**kwargs?它们对函数的灵活性有何帮助?

  3. 递归函数虽然简洁,但可能存在性能或内存问题。你能想到哪些替代递归的迭代实现方式?