Python 编程 - 函数

在 Python 开发中,函数是组织和复用代码的核心结构。通过 def 关键字定义函数,可以接收输入参数、执行特定逻辑并返回结果。下面详细介绍函数定义的各种语法和用法。

1. 基本语法

def 函数名(参数列表):
    """可选的文档字符串"""
    # 函数体
    return 返回值   # 如果没有 return,默认返回 None

示例

def greet(name):
    """向指定的人打招呼"""
    return f"Hello, {name}!"

print(greet("Alice"))  # 输出: Hello, Alice!

2. 参数类型

Python 函数支持非常灵活的参数传递方式。

2.1 位置参数

调用时按定义顺序传入。

def power(base, exponent):
    return base ** exponent

print(power(2, 3))  # 8

2.2 默认参数

为参数提供默认值,调用时可省略。注意:默认参数必须是不可变对象(如 None、数字、字符串),避免使用列表、字典等可变对象(否则会跨调用累积状态)。

def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet("Bob"))           # Hello, Bob!
print(greet("Bob", "Hi"))     # Hi, Bob!

2.3 关键字参数

调用时显式指定参数名,顺序可任意。

print(greet(greeting="Good morning", name="Charlie"))

2.4 可变位置参数 *args

接收任意多个位置参数,在函数内部以元组形式存在。

def sum_all(*args):
    return sum(args)

print(sum_all(1, 2, 3, 4))   # 10

2.5 可变关键字参数 **kwargs

接收任意多个关键字参数,在函数内部以字典形式存在。

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=30, city="New York")

2.6 参数解包

调用函数时,可用 *** 将序列/字典解包为独立参数。

nums = [2, 3]
print(power(*nums))          # 2**3 = 8

params = {"base": 5, "exponent": 2}
print(power(**params))       # 5**2 = 25

2.7 参数定义顺序(从最不特殊到最特殊)

def func(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
    pass
  • / 前的参数为仅位置参数(不能通过关键字传入)。
  • /* 之间的参数可位置也可关键字。
  • * 后的参数为仅关键字参数(必须通过关键字传入)。
def func(a, b, /, c, *, d):
    print(a, b, c, d)

func(1, 2, 3, d=4)   # 正确
# func(1, 2, c=3, d=4) 也正确
# func(1, 2, 3, 4)      # 错误:d 仅关键字
# func(a=1, b=2, c=3, d=4) # 错误:a,b 仅位置

3. 返回值

  • 使用 return 返回一个值;不写 return 或只写 return 则返回 None
  • 可返回多个值(实际是一个元组)。
def swap(a, b):
    return b, a

x, y = swap(1, 2)   # x=2, y=1

4. 文档字符串(Docstring)

紧贴函数体第一行的多行字符串,用于解释函数用途、参数和返回值。可通过 help(函数名)函数名.__doc__ 查看。

def add(a, b):
    """计算两个数的和。

    参数:
        a (int/float): 第一个数
        b (int/float): 第二个数

    返回:
        int/float: 两数之和
    """
    return a + b

print(add.__doc__)

5. 变量作用域

  • 函数内部赋值的变量默认为局部变量,只在函数内可见。
  • 使用 global 声明全局变量(尽量避免使用)。
  • 使用 nonlocal 声明外层(非全局)函数的变量。
x = 10          # 全局变量
def outer():
    y = 20      # 外层变量
    def inner():
        nonlocal y
        y = 30
        global x
        x = 100
    inner()
    print(y)    # 30
outer()
print(x)        # 100

6. Lambda 表达式(匿名函数)

用于简单单行函数,自动返回表达式结果。语法:lambda 参数: 表达式

square = lambda x: x ** 2
print(square(5))   # 25

# 常用在排序、过滤等
points = [(1, 2), (3, 1), (5, -1)]
points.sort(key=lambda p: p[1])   # 按第二个元素排序
print(points)   # [(5, -1), (3, 1), (1, 2)]

7. 函数是一等对象

可以赋值给变量、作为参数传递、作为返回值返回。

def apply(func, value):
    return func(value)

def double(x):
    return x * 2

result = apply(double, 5)   # 10

8. 类型注解(Type Hints)

Python 3.5+ 支持可选的类型标注,提高代码可读性和 IDE 支持,运行时不会检查类型。

def divide(a: float, b: float) -> float:
    """返回 a / b"""
    return a / b

9. 最佳实践

  • 命名:小写字母加下划线(snake_case),动词或动词短语(get_user, calculate_total)。
  • 单一职责:一个函数只做一件事。
  • 不要滥用可变默认参数def func(items=[]) 是错误的,应使用 def func(items=None) 并在内部初始化为 []
  • 显式优于隐式:尽量使用明确的参数传递,少用 *args**kwargs 除非必要。
  • 加上文档字符串:复杂函数必须写清楚参数和返回值含义。

10. 完整示例

def calculate_average(numbers: list, round_digits: int = 2) -> float:
    """计算列表的平均值,并可选择保留小数位数。

    Args:
        numbers: 数字列表(空列表时返回 0.0)
        round_digits: 四舍五入保留的小数位数,默认 2

    Returns:
        平均值(float)
    """
    if not numbers:
        return 0.0
    avg = sum(numbers) / len(numbers)
    return round(avg, round_digits)

# 调用
print(calculate_average([10, 20, 30]))           # 20.0
print(calculate_average([], round_digits=1))    # 0.0

掌握函数定义是写出清晰、可维护 Python 代码的基础。建议结合 pytest 等工具为函数编写单元测试,确保行为符合预期。

posted @ 2026-06-15 09:11  箫笛  阅读(1)  评论(0)    收藏  举报