Python 零基础入门系列(七):函数基础知识(上)

Python 零基础入门系列(七):函数基础知识(上) Python 零基础入门系列七函数基础知识上 系列说明欢迎来到《Python 零基础入门系列》第七篇前六篇我们掌握了基础语法、运算符、流程控制、字符串、列表元组和字典集合。 更新时间2026 年 3 月 19 日 本篇你将学到函数的概念与作用、函数的定义和调用、函数的四种参数类型、函数的返回值以及 3 个函数实战练习。⏱️ 预计阅读时间50-60 分钟 | 实践时间40-50 分钟 前置知识已完成前六篇基础语法、运算符、流程控制、字符串、列表元组、字典集合✍️ 作者书到用时方恨少! 完整目录┌─────────────────────────────────────────────────────────────┐ │ 本篇博客内容导航 │ ├─────────────────────────────────────────────────────────────┤ │ 第一部分函数基础概念 │ │ ├── 1. 什么是函数 │ │ ├── 2. 为什么要使用函数 │ │ └── 3. 函数的基本结构 │ ├─────────────────────────────────────────────────────────────┤ │ 第二部分函数的定义和调用 │ │ ├── 4. def 关键字详解 │ │ ├── 5. 函数命名规范 │ │ └── 6. 调用函数的方式 │ ├─────────────────────────────────────────────────────────────┤ │ 第三部分函数的参数 │ │ ├── 7. 位置参数 │ │ ├── 8. 关键字参数 │ │ ├── 9. 默认参数 │ │ └── 10. 可变参数*args/**kwargs │ ├─────────────────────────────────────────────────────────────┤ │ 第四部分函数的返回值 │ │ ├── 11. return 语句详解 │ │ ├── 12. 返回多个值 │ │ └── 13. 无返回值的情况 │ ├─────────────────────────────────────────────────────────────┤ │ 第五部分综合实战练习 │ │ ├── 14. 练习一计算器函数 │ │ ├── 15. 练习二数据处理函数 │ │ └── 16. 练习三工具函数库 │ └─────────────────────────────────────────────────────────────┘第一部分函数基础概念1. 什么是函数 定义函数Function是一段可重复使用的代码块用于完成特定任务。函数接受输入参数进行处理返回输出返回值。┌─────────────────────────────────────────────────────────────┐ │ 函数的本质 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 输入参数 → [ 函数处理 ] → 输出返回值 │ │ │ │ │ └── 可重复调用 │ │ │ │ 类比理解 │ │ ────────── │ │ • 函数 一台机器 │ │ • 参数 原材料 │ │ • 返回值 成品 │ │ • 调用 启动机器 │ │ │ │ 生活例子 │ │ ────────── │ │ • 洗衣机函数输入脏衣服 → 输出干净衣服 │ │ • 计算器函数输入数字和运算 → 输出结果 │ │ • 榨汁机函数输入水果 → 输出果汁 │ │ │ └─────────────────────────────────────────────────────────────┘2. 为什么要使用函数 核心优势┌─────────────────────────────────────────────────────────────┐ │ 使用函数的好处 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ✅ 1. 代码复用DRY 原则 │ │ ═══════════════ │ │ 避免重复代码一次定义多次调用 │ │ Dont Repeat Yourself │ │ │ │ ✅ 2. 模块化组织 │ │ ══════════ │ │ 将复杂问题分解为小问题每个函数解决一个问题 │ │ │ │ ✅ 3. 易于维护 │ │ ════════ │ │ 修改一处全局生效不需要到处改代码 │ │ │ │ ✅ 4. 提高可读性 │ │ ════════ │ │ 函数名表达意图代码更易理解 │ │ │ │ ✅ 5. 便于测试 │ │ ════════ │ │ 可以单独测试每个函数定位问题更容易 │ │ │ └─────────────────────────────────────────────────────────────┘ 对比示例# ❌ 不使用函数 - 代码重复 print( * 40) print(欢迎用户 1) print( * 40) print( * 40) print(欢迎用户 2) print( * 40) print( * 40) print(欢迎用户 3) print( * 40) # ✅ 使用函数 - 代码复用 def print_welcome(name): print( * 40) print(f欢迎{name}) print( * 40) print_welcome(用户 1) print_welcome(用户 2) print_welcome(用户 3)3. 函数的基本结构 函数组成要素┌─────────────────────────────────────────────────────────────┐ │ 函数结构图 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ def 函数名 (参数 1, 参数 2, ...): │ │ 文档字符串可选 │ │ # 函数体 │ │ 语句 1 │ │ 语句 2 │ │ ... │ │ return 返回值可选 │ │ │ │ ───────────────────────────────────────────────────────── │ │ │ │ 组成要素 │ │ │ │ │ ├── def → 关键字声明函数定义 │ │ ├── 函数名 → 函数的标识符 │ │ ├── 参数列表 → 接收外部输入可空 │ │ ├── : → 冒号表示函数体开始 │ │ ├── 文档字符串 → 说明函数功能可选但推荐 │ │ ├── 函数体 → 缩进的代码块 │ │ └── return → 返回结果可选 │ │ │ └─────────────────────────────────────────────────────────────┘第二部分函数的定义和调用4. def 关键字详解 定义语法# 基本语法 def 函数名 (参数列表): 文档字符串 函数体 return 返回值 # 示例定义一个简单的函数 def greet(): 打招呼函数 print(Hello, Python!) # 调用函数 greet() # 输出Hello, Python! 完整示例# 定义函数 def say_hello(name): 向指定的人打招呼 print(f你好{name}) print(欢迎学习 Python) # 调用函数 say_hello(小明) say_hello(小红) # 输出 # 你好小明 # 欢迎学习 Python # 你好小红 # 欢迎学习 Python5. 函数命名规范 命名规则┌─────────────────────────────────────────────────────────────┐ │ 函数命名规范 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ✅ 推荐做法 │ │ ═══════ │ │ • 使用小写字母 │ │ • 多个单词用下划线分隔snake_case │ │ • 名称要有意义表达函数功能 │ │ • 动词开头表示动作 │ │ │ │ 示例 │ │ • calculate_sum() ✅ │ │ • get_user_info() ✅ │ │ • print_report() ✅ │ │ • is_valid() ✅ │ │ │ │ ───────────────────────────────────────────────────────── │ │ │ │ ❌ 避免做法 │ │ ═══════ │ │ • 使用大写字母开头那是类的命名方式 │ │ • 使用中文命名可能兼容性问题 │ │ • 名称太短或无意义 │ │ • 与内置函数同名如 list、str、max 等 │ │ │ │ 示例 │ │ • CalculateSum() ❌ │ │ • 计算和 () ❌ │ │ • a() / fn() ❌ │ │ • list() / str() ❌覆盖内置函数 │ │ │ └─────────────────────────────────────────────────────────────┘ 示例对比# ✅ 好的命名 def calculate_area(width, height): 计算矩形面积 return width * height def is_even(number): 判断是否为偶数 return number % 2 0 def get_max_value(numbers): 获取列表中的最大值 return max(numbers) # ❌ 不好的命名 def a(b, c): # 无意义 return b * c def 计算面积 (宽高): # 中文命名 return 宽 * 高 def list(items): # 覆盖内置函数 return items6. 调用函数的方式 基本调用# 定义函数 def greet(name): print(fHello, {name}!) # 调用方式 1直接调用 greet(小明) # 调用方式 2赋值给变量 result greet(小红) # 注意greet 没有 returnresult 是 None # 调用方式 3作为参数传递 def welcome(func, name): func(name) welcome(greet, 小刚) # 调用方式 4在表达式中使用 def get_length(text): return len(text) if get_length(Hello) 3: print(字符串长度大于 3)第三部分函数的参数7. 位置参数 定义位置参数Positional Arguments是按照参数位置传递的参数调用时参数的顺序必须与定义时一致。 示例# 定义函数 def introduce(name, age, city): print(f我叫{name}今年{age}岁来自{city}) # 调用 - 位置必须对应 introduce(小明, 18, 北京) # ✅ 正确 # 我叫小明今年 18 岁来自北京 # 调用 - 顺序错误会导致问题 introduce(北京, 18, 小明) # ❌ 逻辑错误 # 我叫北京今年 18 岁来自小明 # 调用 - 参数数量不匹配 # introduce(小明, 18) # ❌ TypeError: 缺少 1 个参数 # introduce(小明, 18, 北京, 额外) # ❌ TypeError: 多了 1 个参数8. 关键字参数 定义关键字参数Keyword Arguments是通过参数名传递的参数调用时可以不按顺序但必须指定参数名。 示例# 定义函数 def introduce(name, age, city): print(f我叫{name}今年{age}岁来自{city}) # 调用 - 使用关键字参数顺序可以打乱 introduce(name小明, age18, city北京) # ✅ introduce(age18, city北京, name小明) # ✅ 顺序不同也可以 introduce(小明, city北京, age18) # ✅ 混合使用 # 混合使用规则位置参数必须在关键字参数之前 introduce(小明, age18, city北京) # ✅ # introduce(name小明, 18, 北京) # ❌ 语法错误9. 默认参数 定义默认参数Default Arguments是在定义时给参数指定默认值调用时可以不传该参数。 示例# 定义带默认参数的函数 def greet(name, message你好): print(f{message}{name}) # 调用 - 使用默认值 greet(小明) # 你好小明 # 调用 - 覆盖默认值 greet(小明, Hello) # Hello小明 greet(小明, messageWelcome) # Welcome小明 # 多个默认参数 def create_user(name, age18, city北京, vipFalse): print(f姓名{name}, 年龄{age}, 城市{city}, VIP: {vip}) create_user(小明) # 只用必填参数 create_user(小红, 20) # 覆盖 age create_user(小刚, city上海, vipTrue) # 覆盖 city 和 vip⚠️ 重要注意事项# ❌ 错误默认参数使用可变对象 def add_item(item, items[]): # 危险 items.append(item) return items print(add_item(1)) # [1] print(add_item(2)) # [1, 2] 预期是 [2]但实际是 [1, 2] print(add_item(3)) # [1, 2, 3] 预期是 [3]但实际是 [1, 2, 3] # ✅ 正确使用 None 作为默认值 def add_item(item, itemsNone): if items is None: items [] items.append(item) return items print(add_item(1)) # [1] print(add_item(2)) # [2] print(add_item(3)) # [3]10. 可变参数*args/**kwargs 定义可变参数允许函数接收任意数量的参数。*args接收任意数量的位置参数打包成元组**kwargs接收任意数量的关键字参数打包成字典 *args 示例# 接收任意数量的位置参数 def sum_all(*args): 计算所有参数的和 total 0 for num in args: total num return total print(sum_all(1)) # 1 print(sum_all(1, 2, 3)) # 6 print(sum_all(1, 2, 3, 4, 5)) # 15 # args 是元组 def print_args(*args): print(f类型{type(args)}) print(f内容{args}) print_args(1, 2, 3) # 类型class tuple # 内容(1, 2, 3) # 混合使用 def mix_func(a, b, *args): print(fa{a}, b{b}, args{args}) mix_func(1, 2, 3, 4, 5) # a1, b2, args(3, 4, 5) **kwargs 示例# 接收任意数量的关键字参数 def print_info(**kwargs): 打印所有关键字参数 print(f类型{type(kwargs)}) for key, value in kwargs.items(): print(f{key}: {value}) print_info(name小明, age18, city北京) # 类型class dict # name: 小明 # age: 18 # city: 北京 # 混合使用 def full_func(a, b, *args, **kwargs): print(fa{a}, b{b}) print(fargs{args}) print(fkwargs{kwargs}) full_func(1, 2, 3, 4, name小明, age18) # a1, b2 # args(3, 4) # kwargs{name: 小明, age: 18} 参数顺序规则┌─────────────────────────────────────────────────────────────┐ │ 参数定义顺序 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 正确顺序 │ │ ═══════ │ │ def func(位置参数默认参数*args, **kwargs): │ │ │ │ 示例 │ │ def func(a, b, c10, d20, *args, **kwargs): │ │ pass │ │ │ │ ───────────────────────────────────────────────────────── │ │ │ │ 错误顺序 │ │ ═══════ │ │ def func(*args, a, b): # ❌ 位置参数不能在*args 之后 │ │ def func(a1, b): # ❌ 默认参数不能在位置参数之前 │ │ │ └─────────────────────────────────────────────────────────────┘第四部分函数的返回值11. return 语句详解 定义return 语句用于从函数返回一个值给调用者。return 执行后函数立即结束。 示例# 返回单个值 def add(a, b): return a b result add(3, 5) print(result) # 8 # return 后代码不执行 def test(): return 1 print(这行不会执行) # 永远不会执行 # 条件返回 def get_grade(score): if score 90: return A elif score 80: return B elif score 70: return C else: return D print(get_grade(85)) # B12. 返回多个值 示例# 返回多个值实际是返回元组 def get_user_info(): name 小明 age 18 city 北京 return name, age, city # 接收多个值元组解包 info get_user_info() print(info) # (小明, 18, 北京) print(type(info)) # class tuple # 解包接收 name, age, city get_user_info() print(f{name}, {age}岁{city}) # 部分接收 name, *rest get_user_info() print(f姓名{name}, 其他{rest}) # 返回字典更清晰 def get_user_info_dict(): return {name: 小明, age: 18, city: 北京} info get_user_info_dict() print(info[name]) # 小明13. 无返回值的情况 示例# 没有 return 语句 def greet(name): print(fHello, {name}!) result greet(小明) print(result) # None # 只有 return 没有值 def do_nothing(): return result do_nothing() print(result) # None # 验证 def test(): pass # 空函数 print(test()) # None 返回值总结┌─────────────────────────────────────────────────────────────┐ │ 返回值情况总结 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 情况 1return 值 │ │ ═══════════ │ │ def func(): │ │ return 42 │ │ → 返回 42 │ │ │ │ ───────────────────────────────────────────────────────── │ │ │ │ 情况 2return无值 │ │ ══════════════ │ │ def func(): │ │ return │ │ → 返回 None │ │ │ │ ───────────────────────────────────────────────────────── │ │ │ │ 情况 3无 return 语句 │ │ ════════════ │ │ def func(): │ │ print(Hello) │ │ → 返回 None │ │ │ └─────────────────────────────────────────────────────────────┘第五部分综合实战练习 重要说明以下是练习题目请读者先自行思考并完成代码之后再查看单独发布的答案讲解博客进行核对14. 练习一计算器函数 练习要求创建一个计算器模块包含以下函数add(a, b)- 计算两数之和subtract(a, b)- 计算两数之差multiply(a, b)- 计算两数之积divide(a, b)- 计算两数之商需要处理除数为 0 的情况calculate(a, b, operator)- 根据运算符调用上述函数 提示除数为 0 时返回错误提示calculate 函数支持 , -, *, / 四种运算符未知运算符返回错误提示 练习代码框架# 请在此处完成你的代码 # 定义 add 函数 # 定义 subtract 函数 # 定义 multiply 函数 # 定义 divide 函数 # 定义 calculate 函数 # 测试代码 if __name__ __main__: print( 计算器测试 ) print(f5 3 {add(5, 3)}) print(f5 - 3 {subtract(5, 3)}) print(f5 * 3 {multiply(5, 3)}) print(f5 / 3 {divide(5, 3)}) print(f5 / 0 {divide(5, 0)}) print(fcalculate(10, 5, ) {calculate(10, 5, )}) print(fcalculate(10, 5, %) {calculate(10, 5, %)})15. 练习二数据处理函数 练习要求创建一组数据处理函数get_statistics(numbers)- 统计列表的数字信息返回最大值、最小值、平均值、总和用字典返回filter_by_condition(numbers, condition)- 根据条件过滤列表condition 可以是 even偶数、odd奇数、positive正数、negative负数返回过滤后的新列表transform_list(numbers, transform_type)- 转换列表transform_type 可以是 square平方、double翻倍、abs绝对值返回转换后的新列表 提示使用字典返回多个统计值注意处理空列表的情况使用条件判断处理不同的 condition 和 transform_type 练习代码框架# 请在此处完成你的代码 # 定义 get_statistics 函数 # 定义 filter_by_condition 函数 # 定义 transform_list 函数 # 测试代码 if __name__ __main__: print( 数据处理测试 ) nums [1, 2, 3, 4, 5, -6, -7, 0] print(f原始列表{nums}) print(f统计信息{get_statistics(nums)}) print(f偶数{filter_by_condition(nums, even)}) print(f奇数{filter_by_condition(nums, odd)}) print(f正数{filter_by_condition(nums, positive)}) print(f平方{transform_list(nums, square)}) print(f翻倍{transform_list(nums, double)})16. 练习三工具函数库 练习要求创建一个实用工具函数库is_palindrome(text)- 判断是否为回文忽略大小写和空格返回 True/Falsecount_chars(text)- 统计字符频率返回字典键为字符值为出现次数format_currency(amount, currency¥)- 格式化金额保留 2 位小数添加千位分隔符添加货币符号generate_password(length8, use_digitsTrue, use_specialTrue)- 生成随机密码length: 密码长度use_digits: 是否包含数字use_special: 是否包含特殊字符返回生成的密码字符串 提示回文判断需要预处理字符串转小写、去空格字符频率统计可以用字典金额格式化可以用字符串格式化密码生成需要导入 random 模块 练习代码框架# 请在此处完成你的代码 # 需要导入 random 模块 # 定义 is_palindrome 函数 # 定义 count_chars 函数 # 定义 format_currency 函数 # 定义 generate_password 函数 # 测试代码 if __name__ __main__: print( 工具函数测试 ) print(f上海自来水来自海上 是回文吗{is_palindrome(上海自来水来自海上)}) print(fhello 是回文吗{is_palindrome(hello)}) print(fA man a plan a canal Panama 是回文吗{is_palindrome(A man a plan a canal Panama)}) print(f\nhelloworld 字符频率{count_chars(helloworld)}) print(f\n1234567.89 格式化{format_currency(1234567.89)}) print(f1234567.89 美元格式化{format_currency(1234567.89, $)}) print(f\n生成密码 (8 位): {generate_password(8)}) print(f生成密码 (12 位): {generate_password(12)}) print(f生成密码 (无数字): {generate_password(8, use_digitsFalse)}) 总结与下一篇预告本篇核心知识点回顾┌─────────────────────────────────────────────────────────────┐ │ 知识点思维导图 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Python 函数基础上 │ │ │ │ │ ├── 函数概念 │ │ │ ├── 什么是函数 │ │ │ ├── 为什么用函数 │ │ │ └── 函数结构 │ │ │ │ │ ├── 定义与调用 │ │ │ ├── def 关键字 │ │ │ ├── 命名规范 │ │ │ └── 调用方式 │ │ │ │ │ ├── 函数参数 │ │ │ ├── 位置参数 │ │ │ ├── 关键字参数 │ │ │ ├── 默认参数 │ │ │ └── 可变参数 (*args/**kwargs) │ │ │ │ │ ├── 返回值 │ │ │ ├── return 语句 │ │ │ ├── 返回多个值 │ │ │ └── 无返回值 (None) │ │ │ │ │ └── 实战练习 │ │ ├── 计算器函数 │ │ ├── 数据处理函数 │ │ └── 工具函数库 │ │ │ └─────────────────────────────────────────────────────────────┘✅ 学习检查清单理解函数的概念和作用掌握函数的定义语法遵循函数命名规范熟练使用位置参数和关键字参数理解默认参数的注意事项掌握可变参数的使用理解 return 语句的作用完成 3 个实战练习 下一篇预告《Python 零基础入门系列八函数基础知识下》┌─────────────────────────────────────────────────────────────┐ │ 第八篇内容预告 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 1️⃣ 函数的文档注释 │ │ • 文档字符串的写法 │ │ • 参数说明格式 │ │ • 返回值说明格式 │ │ │ │ 2️⃣ 函数的嵌套调用 │ │ • 函数调用函数 │ │ • 递归的概念初步 │ │ │ │ 3️⃣ 局部变量和全局变量 │ │ • 作用域的概念 │ │ • local vs global │ │ • global 关键字 │ │ │ │ 4️⃣ 变量作用域规则 │ │ • LEGB 规则 │ │ • 作用域查找顺序 │ │ │ │ 5️⃣ 综合实战 │ │ • 带文档的函数库 │ │ • 作用域实验 │ │ • 嵌套函数应用 │ │ │ └─────────────────────────────────────────────────────────────┘ 完整系列更新计划┌─────────────────────────────────────────────────────────────┐ │ Python 零基础入门系列 · 完整规划12 篇版 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 第一篇Python 认知 环境搭建 基础语法 │ │ ✅ 已完成 │ │ │ │ 第二篇常用运算符完全详解 │ │ ✅ 已完成 │ │ │ │ 第三篇流程控制——条件判断与循环结构 │ │ ✅ 已完成 │ │ │ │ 第四篇字符串常用操作详解 │ │ ✅ 已完成 │ │ │ │ 第五篇列表与元组——序列操作全解析 │ │ ✅ 已完成 │ │ │ │ 第六篇字典与集合——映射与去重操作 │ │ ✅ 已完成 │ │ │ │ 第七篇本篇函数基础知识上 │ │ ✅ 已完成 │ │ │ │ 第八篇函数基础知识下 │ │ 敬请期待 │ │ • 函数的文档注释 │ │ • 函数的嵌套调用 │ │ • 局部变量和全局变量 │ │ │ │ 第九篇函数进阶知识 │ │ 敬请期待 │ │ • 匿名函数lambda │ │ • 递归函数 │ │ • 高阶函数 │ │ │ │ 第十篇闭包和装饰器 │ │ 敬请期待 │ │ • 闭包的概念与原理 │ │ • 装饰器的语法与用法 │ │ • 带参数的装饰器 │ │ │ │ 第十一篇模块和包 │ │ 敬请期待 │ │ • 模块的导入与使用 │ │ • 常用标准库模块 │ │ • 包的创建与结构 │ │ │ │ 第十二篇及后续更多进阶内容 │ │ 敬请期待 │ │ • 文件操作 │ │ • 异常处理 │ │ • 面向对象编程 │ │ │ └─────────────────────────────────────────────────────────────┘ 系列进度可视化进度条████████████████████████░░ 7/12 完成 ✅ ✅ ✅ ✅ ✅ ✅ ✅ 推荐学习资源类型名称链接官网Python 官方网站https://www.python.org文档Python 官方文档中文https://docs.python.org/zh-cn/3/教程菜鸟教程 Pythonhttps://www.runoob.com/python3/教程廖雪峰 Python 教程https://www.liaoxuefeng.com/wiki/1016959663602400练习LeetCodehttps://leetcode.cn练习CheckiO游戏化学习https://checkio.org社区Stack Overflowhttps://stackoverflow.com社区Python 中文社区https://python-china.org 结语函数是编程的基石掌握函数你就掌握了代码复化和模块化的钥匙。恭喜你完成了 Python 入门系列的第七篇现在你已经✅ 理解了函数的概念和作用✅ 掌握了函数的定义和调用✅ 学会了四种参数类型的使用✅ 理解了返回值的各种情况✅ 完成了 3 个实战练习题目下一步建议先独立完成 3 个实战练习不要看答案遇到问题先思考再查阅前六篇内容完成后再查看单独发布的答案讲解博客准备迎接第八篇——函数基础下记住多动手写代码函数才能用得熟练 更新时间2026 年 3 月 19 日✍️ 作者书到用时方恨少! | 专注 Python 教学与 AI 技术分享 如有疑问欢迎在评论区留言讨论如果觉得这篇文章有帮助请点赞、收藏⭐、转发让更多的小伙伴一起加入 Python 学习的行列 系列文章索引篇数主题状态链接第一篇Python 认知 环境搭建 基础语法✅ 已完成点击查看第二篇常用运算符完全详解✅ 已完成点击查看第三篇流程控制——条件判断与循环结构✅ 已完成点击查看第四篇字符串常用操作详解✅ 已完成点击查看第五篇列表与元组——序列操作全解析✅ 已完成点击查看第六篇字典与集合——映射与去重操作✅ 已完成点击查看第七篇函数基础知识上✅ 已完成当前文章第八篇函数基础知识下 敬请期待敬请期待第九篇函数进阶知识 敬请期待敬请期待第十篇闭包和装饰器 敬请期待敬请期待第十一篇模块和包 敬请期待敬请期待第十二篇更多进阶内容 敬请期待敬请期待 订阅提醒关注我不错过每一篇更新 答案讲解博客将单独发布请先完成练习后再查看答案