Python-函数

一、为什么需要函数?

问题:同一段代码写了 10 遍,改一处要改 10 处。

解决:把代码封装成函数,需要时调用即可。

函数的好处

  1. 代码复用——写一次,用多次
  2. 模块化——分工明确,易于维护
  3. 抽象——隐藏实现细节,只关心「做什么」

二、函数的定义与调用

2.1 基本语法

def 函数名(参数1, 参数2, ...):
    """文档字符串(说明函数功能)"""
    函数体
    return 返回值  # 可选

2.2 示例

def greet(name):
    """向用户打招呼"""
    print(f"Hello, {name}!")

greet("张三")       # 调用
help(greet)         # 查看文档

2.3 定义函数的规则

  1. 函数名是标识符,遵循命名规范
  2. 函数名后必须有 ()
  3. 函数体必须缩进
  4. return 返回结果;没有 return 则返回 None

三、参数详解(重点)

3.1 形参与实参

def add(a, b):    # a, b 是形参(形式参数)
    return a + b

add(3, 5)         # 3, 5 是实参(实际参数)

3.2 位置参数与关键字参数

def info(name, age, city):
    print(f"{name}, {age}岁, {city}")

info("张三", 20, "北京")              # 位置参数
info(name="李四", age=22, city="上海")  # 关键字参数
info("王五", city="广州", age=25)      # 混合(位置在前)

3.3 默认参数

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

greet("张三")              # Hello, 张三!
greet("李四", "Hi")        # Hi, 李四!

⚠️ 默认参数不要用可变对象

# 错误!
def bad(lst=[]):
    lst.append(1)
    return lst

# 正确
def good(lst=None):
    if lst is None:
        lst = []
    lst.append(1)
    return lst

3.4 不定长参数 *args

def total(*args):
    print(args)    # 元组
    return sum(args)

total(1, 2, 3, 4)  # 10

3.5 不定长关键字参数 **kwargs

def show(**kwargs):
    print(kwargs)  # 字典

show(name="张三", age=20)
# {'name': '张三', 'age': 20}

3.6 参数顺序

def func(a, b, c=0, *args, **kwargs):
    pass

# 顺序:位置参数 → 默认参数 → *args → **kwargs

3.7 解包传参

def add(a, b, c):
    return a + b + c

add(*[1, 2, 3])                        # 序列解包
add(**{"a": 1, "b": 2, "c": 3})        # 字典解包

3.8 参数传递机制

Python 是对象引用传递

  • 不可变对象(int、str、tuple):函数内修改不影响外部
  • 可变对象(list、dict):函数内修改会影响外部
def modify(lst):
    lst.append(4)

nums = [1, 2, 3]
modify(nums)
print(nums)  # [1, 2, 3, 4]

四、返回值

def get_min_max(nums):
    return min(nums), max(nums)  # 返回元组

minimum, maximum = get_min_max([3, 1, 4, 1, 5])
print(minimum, maximum)  # 1 5

# 没有 return 返回 None
def do_nothing():
    pass
print(do_nothing())  # None

五、函数嵌套调用

def square(x):
    return x ** 2

def sum_of_squares(a, b):
    return square(a) + square(b)

print(sum_of_squares(3, 4))  # 25

六、变量作用域

6.1 局部变量与全局变量

x = 10  # 全局变量

def func():
    x = 20  # 局部变量,不影响全局
    print(x)  # 20

func()
print(x)  # 10

6.2 global 关键字

count = 0

def increment():
    global count
    count += 1

increment()
print(count)  # 1

6.3 nonlocal 关键字

def outer():
    x = 10
    def inner():
        nonlocal x
        x = 20
    inner()
    print(x)  # 20

outer()

6.4 LEGB 规则

查找变量名的顺序:Local → Enclosing → Global → Built-in


七、递归

函数调用自身,必须有终止条件

def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))  # 120

递归三要素

  1. 终止条件(递归出口)
  2. 递归公式
  3. 每次递归向终止条件靠近

八、匿名函数 lambda

# 语法:lambda 参数: 表达式
square = lambda x: x ** 2
print(square(5))  # 25

# 常用于 sorted 的 key
students = [("张三", 85), ("李四", 92), ("王五", 78)]
students.sort(key=lambda s: s[1], reverse=True)
print(students)

九、练习题

基础题

1. 编写 is_prime(n) 判断素数。

2. 编写函数,接收任意个数数字,返回平均值。

3. 编写函数,返回字符串中 (大写个数, 小写个数, 数字个数)。

4. 用 lambda 将 [("apple",3),("ban",2)] 按数量降序排列。

5. 编写递归函数求 1+2+...+n。

进阶题

6. 实现二分查找(递归版)。

7. 编写装饰器 @timer 打印函数执行耗时。

参考答案

点击展开参考答案

import time

def is_prime(n):
    if n < 2: return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0: return False
    return True

def average(*args):
    return sum(args) / len(args) if args else 0

def count_chars(s):
    return (sum(1 for c in s if c.isupper()),
            sum(1 for c in s if c.islower()),
            sum(1 for c in s if c.isdigit()))

def sum_n(n):
    if n <= 0: return 0
    return n + sum_n(n - 1)

def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"{func.__name__} 耗时: {time.time()-start:.4f}s")
        return result
    return wrapper
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值