Alt

⛳️个人主页⛳️
🐹今日诗词:东风吹雨过青山,却望千门草色闲🐹

1

1. 🎁 函数是什么

想象一下,函数就像一个自动咖啡机☕:

  • 你放入咖啡豆和水(输入)
  • 机器按照固定步骤制作(处理过程)
  • 最后给你一杯香浓的咖啡(输出)
# 函数就是一段可以重复使用的代码
def make_coffee(beans, water):
    # 制作咖啡的过程
    coffee = beans + water + "搅拌搅拌"
    return coffee

# 每次想喝咖啡,只需要调用函数
my_coffee = make_coffee("阿拉比卡豆", "纯净水")

2. 📝 语法格式

def 函数名(参数1, 参数2, ...):
    """函数说明文档(可选)"""
    函数体(具体要做的事)
    return 返回值(可选)

记住口诀:def开头,冒号结尾,缩进很重要!😊

# 完整示例
def calculate_area(length, width):
    """计算矩形面积"""
    area = length * width
    return area

# 调用函数
result = calculate_area(5, 3)  # result = 15

3. 📦 函数参数

函数参数就像外卖订单🍔 - 你要告诉店家你想要什么!

3.1 位置参数(必须按顺序)

def introduce(name, age, city):
    print(f"我叫{name},今年{age}岁,来自{city}")

introduce("小明", 18, "北京")  # ✅ 正确
# introduce(18, "小明", "北京")  # ❌ 顺序错了会出问题!

3.2 默认参数(有默认值)

def order_coffee(size="中杯", sugar="少糖"):
    print(f"您点了{size}{sugar}的咖啡")

order_coffee()                    # 中杯,少糖的咖啡
order_coffee("大杯")             # 大杯,少糖的咖啡
order_coffee("大杯", "无糖")     # 大杯,无糖的咖啡

3.3 关键字参数(指定参数名)

def create_profile(name, age, hobby):
    print(f"{name}{age}岁,爱好是{hobby}")

# 使用关键字参数,顺序可以随意!
create_profile(age=25, hobby="编程", name="小红")  # ✅
create_profile(name="小刚", hobby="游泳", age=30)  # ✅

3.4 可变参数(*args 和 **kwargs)

# *args:接收任意数量的位置参数
def eat_food(*foods):
    print("今天吃了:")
    for food in foods:
        print(f"- {food}")

eat_food("汉堡", "薯条", "可乐", "冰淇淋")  # 想吃多少写多少!

# **kwargs:接收任意数量的关键字参数
def print_info(**info):
    for key, value in info.items():
        print(f"{key}: {value}")

print_info(name="小明", age=18, city="上海", hobby="打篮球")

4. 🎯 函数返回值

📦 知识点一:返回单个值

核心说明:函数通过 return 返回单一计算结果

def add(a, b):
    return a + b  # 用return返回计算结果

result = add(3, 5)  # 接收返回值
print(result)  # 输出: 8

关键点:

  • return 是函数输出结果的唯一方式
  • 返回值可直接使用或存入变量

📬 知识点二:返回多个值(元组解包)

核心说明:函数可返回元组,通过解包获取多个值

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

# 解包接收多个返回值
minimum, maximum = get_min_max([1, 5, 3, 9, 2])
print(f"最小值:{minimum},最大值:{maximum}")  # 输出: 最小值:1,最大值:9

关键点:

  • 多返回值本质是返回元组 (min, max)
  • 解包语法 a, b = func() 可同时获取多个值

🚫 知识点三:无返回值行为(None)

核心说明:函数无return时默认返回None

def say_hello():
    print("Hello!")  # 只有输出语句
    # 无return语句

result = say_hello()  # 调用函数(输出Hello!)
print(result)  # 输出: None

5. 🏠 变量作用域

📢 知识点一:全局变量(全校可见)

核心:全局变量全局可见

school_motto = "勤奋 诚信 创新"  # 全局变量(全校公告)

def classroom_301():
    print(school_motto)  # ✅ 任何教室都能看到校训

classroom_301()  # 输出:勤奋 诚信 创新

🚪 知识点二:局部变量(仅本班可用)

核心:函数内变量只在本函数内有效

def classroom_301():
    class_secret = "明天有惊喜测验"  # 局部变量(班级秘密)
    print(class_secret)  # ✅ 本班同学知道

# print(class_secret)  # ❌ 其他班级无法知道

📚 知识点三:嵌套作用域(小组在班级内)

核心

  • 内层函数可访问外层变量
  • 外层不能访问内层变量
def classroom_301():
    class_secret = "明天有惊喜测验"
  
    def study_group():
        group_plan = "放学后补习数学"  # 小组内部变量
        print(class_secret)  # ✅ 小组知道班级秘密
  
    study_group()  # 成功输出班级秘密
    # print(group_plan)  # ❌ 班级不知道小组计划

LEGB规则(查找顺序)

  • Local(局部)→ Enclosing(外层函数)→ Global(全局)→ Built-in(内置)
x = "全局变量"

def outer():
    x = "外层函数变量"
  
    def inner():
        x = "局部变量"
        print(x)  # 输出:局部变量
  
    inner()
    print(x)  # 输出:外层函数变量

outer()
print(x)  # 输出:全局变量

6. 🎬 函数执行过程

函数就像一个小型工厂:你提供原材料(参数),它按照固定流程加工,最后给你成品(返回值)。

核心概念

  1. 传入参数:调用函数时传递数据
  2. 执行步骤:按顺序运行函数内代码
  3. 返回结果:通过return输出最终产品
  4. 清理现场:函数结束后,内部变量自动清除

🍰 蛋糕工厂示例

def cake_factory(flavor):
    # 1. 接收原材料
    print(f"收到原料:{flavor}")
  
    # 2. 加工步骤
    mix = f"搅拌{flavor}面糊"
    bake = "烘烤20分钟"
    print(mix)
    print(bake)
  
    # 3. 产出成品
    cake = f"★{flavor}蛋糕★"
    return cake

# 使用工厂
order = "巧克力"  # 下单原料
product = cake_factory(order)  # 工厂加工

print(f"收到成品:{product}")

# 尝试访问工厂内部(会失败)
# print(mix)  # 错误!工厂内部变量已清除

关键理解

  • 函数像临时工厂:接收原料→加工→产出→清理
  • return是交货时刻,之后工厂立即关闭
  • 内部变量如mix是临时工具,外部无法访问
  • 整个过程按代码顺序一步步执行

7. 🔗 链式调用

链式调用就像工厂的流水线作业:前一道工序的输出直接成为下一道工序的输入,形成连续的处理流程

判定是否是奇数

def isOdd(num):
    if num % 2 == 0:
        return False
    else:
        return True

实际上也可以简化写作

print(isOdd(10))

8. 🎪 嵌套调用

核心概念: 嵌套调用就像俄罗斯套娃:在一个函数的执行过程中,又调用了其他函数,形成层层嵌套的执行结构

🌐 多层嵌套示例

def get_user():
    return "Alice"

def greet(user):
    return f"Hello, {user}!"

def display(greeting):
    print(greeting + " 👋")

# 三层嵌套调用
display(greet(get_user()))  # 输出: Hello, Alice! 👋

执行顺序

  1. 最内层:get_user() → 返回"Alice"
  2. 中间层:greet("Alice") → 返回"Hello, Alice!"
  3. 最外层:display("Hello, Alice!") → 打印结果

💡 嵌套调用最佳实践

  1. 层次限制:嵌套不宜过深(建议≤3层)
  2. 功能单一:每个函数只做一件事
  3. 清晰命名:函数名明确表达功能
  4. 错误处理:内层函数应有异常处理

9. 🔄 函数递归

递归就像镜子中的镜子:函数在执行过程中调用自身,将大问题分解成相似的小问题,直到达到最简单的情况。

核心概念

  1. 自调用:函数内部直接或间接调用自身
  2. 问题分解:将复杂问题分解为相同结构的子问题
  3. 基准条件:存在明确的终止条件(递归出口)
  4. 堆栈机制:每次调用创建新的栈帧,后进先出(LIFO)

🧮 阶乘计算示例

def factorial(n):
    # 基准条件:0! = 1
    if n == 0:
        return 1
    # 递归步骤:n! = n * (n-1)!
    else:
        return n * factorial(n-1)

print(factorial(3))  # 输出: 6 (3×2×1=6)

执行过程解析(计算 factorial(3)):

1. factorial(3) = 3 × factorial(2)   → 等待factorial(2)结果
2.   factorial(2) = 2 × factorial(1) → 等待factorial(1)结果
3.     factorial(1) = 1 × factorial(0) → 等待factorial(0)结果
4.       factorial(0) = 1 (基准条件)
5.     factorial(1) = 1 × 1 = 1
6.   factorial(2) = 2 × 1 = 2
7. factorial(3) = 3 × 2 = 6

⚠️ 递归使用要点

要点 说明 示例
必须的基准条件 防止无限递归 if n==0: return 1
问题规模递减 每次递归问题应更小 factorial(n-1)
堆栈深度限制 Python默认约1000层 sys.setrecursionlimit(1500)
尾递归优化 Python不支持,需手动转循环 使用循环替代深层递归

🔄 递归 vs 循环

特性 递归 循环
代码简洁性 ★★★ 更简洁 ★★ 稍繁琐
内存消耗 ★ 栈空间消耗大 ★★★ 内存高效
可读性 ★★ 结构性问题更直观 ★★★ 简单问题更直接
适用场景 树结构、分治算法 线性迭代、性能敏感

关键理解

  • 递归是分而治之的策略,将问题分解为相似子问题
  • 基准条件是递归的安全阀,必不可少
  • 递归调用形成调用栈,深度过大导致栈溢出
  • 适合处理嵌套结构(文件系统、语法树、组合问题)

参数默认值就像餐厅的套餐默认配置:点餐时如果没特别说明,就按默认方案提供,但顾客可以随时自定义。

核心概念

  1. 预设值:定义函数时给参数指定默认值
  2. 可选参数:调用时可省略有默认值的参数
  3. 位置约束:默认参数必须放在非默认参数后面
  4. 默认值计算:默认值在函数定义时确定(仅一次)

10. 🎯 参数默认值

🍔 餐厅点餐示例

def order_food(dish, drink="可乐", side="薯条"):
    """点餐函数:主菜必选,饮料和配菜可选"""
    print(f"🍽️ 您点了:{dish} + {drink} + {side}")

# 使用默认配置
order_food("汉堡")  # 输出:🍽️ 您点了:汉堡 + 可乐 + 薯条

# 自定义部分配置
order_food("炸鸡", "雪碧")  # 输出:🍽️ 您点了:炸鸡 + 雪碧 + 薯条

# 完全自定义
order_food("披萨", "柠檬茶", "沙拉")  # 输出:🍽️ 您点了:披萨 + 柠檬茶 + 沙拉

⚠️ 重要注意事项

1️⃣ 默认值只初始化一次(对可变对象需谨慎)
def add_item(item, cart=[]):  # 默认值为可变对象(列表)
    cart.append(item)
    return cart

# 第一次调用正常
print(add_item("苹果"))  # ['苹果']

# 第二次调用会保留上次结果(通常不是预期行为)
print(add_item("香蕉"))  # ['苹果', '香蕉'] ❌

正确做法:使用None作为占位符

def add_item(item, cart=None):
    if cart is None:  # 每次调用创建新列表
        cart = []
    cart.append(item)
    return cart

print(add_item("苹果"))  # ['苹果']
print(add_item("香蕉"))  # ['香蕉'] ✅
2️⃣ 默认参数必须放在最后
# 正确写法
def func(a, b=1, c=2):
    pass

# 错误写法(会报错)
def func(a=1, b, c):
    pass

🆚 默认参数 vs 必需参数

特性 默认参数 必需参数
定义方式 param=default_value 无默认值
调用要求 可省略 必须提供
位置 必须在非默认参数后 可在任意位置
典型用途 可选配置项 核心输入数据

11. 🏷️ 关键字参数

关键字参数就像快递包裹上的标签:通过明确的参数名指定值,不再依赖顺序,让函数调用更清晰灵活。

核心概念

  1. 按名传递:调用时使用参数名=值的形式
  2. 顺序无关:参数顺序可以任意调整
  3. 可读性强:明确显示每个参数的作用
  4. 结合位置参数:位置参数在前,关键字参数在后

def test(x, y):
    print(f'x = {x}')
    print(f'y = {y}')
    test(x=10, y=20)
    test(y=100, x=200)

形如上述 test(x=10, y=20) 这样的操作, 即为 关键字参数.

🎯 综合练习时间!

现在来个小挑战,测试你是否真的理解了:

题目:写一个函数calculate_grade(score, bonus=0)

  • 计算最终成绩(分数+奖励分)
  • 如果最终成绩>=90,返回"优秀"
  • 如果最终成绩>=80,返回"良好"
  • 如果最终成绩>=60,返回"及格"
  • 否则返回"不及格"

美图分享

在这里插入图片描述

✨🎇谢谢你的阅读和耐心!祝愿你在编程的道路上取得更多的成功与喜悦!"🎇✨🌌
🌟💖📌➕👀 点赞收藏加关注,学习知识不迷路 🌟
🎊✅🚀🎊✅🚀🎊✅🚀🎊✅🚀🎊
👍🔥🚩点赞☀️收藏🌟关注🔥👍
👍🔥🚩点赞☀️收藏🌟关注🔥👍
👍🔥🚩点赞☀️收藏🌟关注🔥👍
💫💫💫💫💫💫💫💫💫💫💫💫💫
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐