day26/60
@浙大疏锦行
DAY 26 函数专题1:函数定义与参数
知识点回顾:
- 函数的定义
- 变量作用域:局部变量和全局变量
- 函数的参数类型:位置参数、默认参数、不定参数
- 传递参数的手段:关键词参数
- 传递参数的顺序:同时出现三种参数类型时
答:以下是用生活场景比喻解释编程知识点,尽量让抽象概念「可视化」:
1. 函数的定义:把重复劳动打包成「万能小工具」
本质:避免重复写代码,把常用功能封装成「黑匣子」,需要时直接调用。
比喻:
- 函数 = 自动贩卖机
- 贩卖机内部的「出货逻辑」是函数的代码(比如投币后弹出饮料)。
- 调用函数 = 按下饮料对应的「按钮编号」(比如按「3 号」买可乐)。
- 参数 = 投币的「金额」或「特殊需求」(比如按「3 号 + 冰」买冰可乐)。
- 返回值 = 弹出的饮料(用
return
把结果「吐出来」)。
例子:
python
# 定义一个「自动贩卖机」函数
def vending_machine(button_number, is_ice=False):if button_number == 3 and is_ice:return "冰可乐"# ...其他逻辑
2. 变量作用域:变量的「活动范围」与「隐私规则」
全局变量:全家可见的「公共物资」
- 特点:在函数外部定义,整个程序都能访问(像客厅的「Wi-Fi 密码」,所有房间都能用)。
- 风险:容易被误改(比如家人误改了 Wi-Fi 密码,导致全家断网)。
局部变量:房间内的「私人物品」
- 特点:在函数内部定义,只能在函数内使用(像卧室的「日记本」,只有自己能看)。
- 安全:不会影响其他函数(别人找不到你的日记本,自然不会改里面的内容)。
比喻场景:
python
wifi_password = "public123" # 全局变量(客厅Wi-Fi密码)def study_room():diary_content = "今天学了编程" # 局部变量(卧室日记本)print(f"在书房用Wi-Fi:{wifi_password}") # 可以访问全局变量# print(diary_content) # 其他函数看不到这个变量!
3. 函数的参数类型:给函数「下订单」的三种方式
① 位置参数:必须按顺序「排队点餐」
- 特点:参数必须按定义顺序传递,像排队买奶茶时「先报甜度,再报配料」。
- 例子:
python
def make_coffee(甜度, 配料): # 位置参数print(f"制作一杯{甜度}的{配料}奶茶") make_coffee("半糖", "珍珠") # 必须按「甜度→配料」顺序传递
- 比喻:像去早餐店说「老板,来 1 个鸡蛋、2 根油条」(数量和顺序必须对)。
② 默认参数:套餐里的「预设选项」
- 特点:参数有默认值,调用时可省略(像点汉堡时默认加番茄,不想加就单独说明)。
- 例子:
python
def make_hamburger(加番茄=True): # 默认加番茄print(f"汉堡是否加番茄:{加番茄}") make_hamburger() # 直接用默认值(加番茄) make_hamburger(False) # 主动取消番茄
- 比喻:像外卖下单时,默认勾选「微辣」,不喜欢辣就手动取消。
③ 不定参数:自助餐的「无限拿取模式」
- 特点:接收任意数量的参数,用
*args
(元组)或**kwargs
(字典)表示。*args
= 接收「多个位置参数」(像往购物车随便加商品)。**kwargs
= 接收「多个关键词参数」(像给商品加标签:颜色 = 红色,尺寸 = XL)。
- 例子:
python
def buffet(*食物, **属性):print(f"拿了:{食物},属性:{属性}") buffet("牛排", "蛋糕", 颜色="棕色", 热量=500) # 任意数量参数
- 比喻:像去自助餐厅,盘子里想装多少菜就装多少(
*args
),还能给菜贴标签(**kwargs
)。
4. 关键词参数:精准「对号入座」的传递方式
- 本质:传递参数时明确指定「参数名 = 值」,不依赖顺序(避免弄错位置)。
- 比喻:
- 像填快递单:「收件人 = 张三,地址 = XX 路 10 号」,顺序不重要,关键是名称对应。
- 对比「位置参数」:如果只说「张三,XX 路 10 号」,可能被误判为「地址 = 张三,收件人 = XX 路 10 号」。
- 例子:
python
def send_package(收件人, 地址):print(f"寄给{收件人},地址{地址}") send_package(地址="XX路10号", 收件人="张三") # 用关键词参数,顺序随意
5. 参数传递顺序:三种参数同时出现时的「排队规则」
规则:必须严格按照「位置参数 → 默认参数 → 不定参数」的顺序排列。
比喻:组装家具的步骤:
- 位置参数 = 先装「固定位置的零件」(如桌腿,必须先装且顺序固定)。
- 默认参数 = 再装「可选配件」(如抽屉,可装可不装,装的话放后面)。
- 不定参数 = 最后处理「多余的零件」(如螺丝,可能有多个,放最后)。
错误示范:
python
def func(默认参数=1, 位置参数): # ❌ 错误!默认参数不能在位置参数前pass
正确顺序示例:
python
def build_table(桌腿数量, 桌面材质="木质", *多余零件, **零件属性):print(f"桌腿:{桌腿数量},桌面:{桌面材质}")print(f"多余零件:{多余零件},属性:{零件属性}")# 调用时顺序:位置参数 → 默认参数(可省略)→ 不定参数
build_table(4, "玻璃", "螺丝", "垫片", 颜色="银色", 尺寸="M")
总结比喻速查表
知识点 | 比喻对象 | 核心逻辑 |
---|---|---|
函数 | 自动贩卖机 | 输入参数(投币)→ 执行逻辑(出货)→ 返回结果 |
全局变量 | 客厅 Wi-Fi 密码 | 全家可见,易被误改 |
局部变量 | 卧室日记本 | 仅限当前函数使用,安全私密 |
位置参数 | 排队点餐(先报甜度) | 顺序必须正确 |
默认参数 | 套餐默认选项(微辣) | 可选,不填就用预设值 |
不定参数 | 自助餐无限拿取 | 任意数量,用 * 或 ** 打包 |
关键词参数 | 快递单填项(收件人 =) | 按名称对号入座,无视顺序 |
参数顺序 | 组装家具(先装桌腿) | 位置→默认→不定,不能打乱 |
通过生活场景联想,编程概念会变得像「日常操作」一样好理解! 😊
作业:
题目1:计算圆的面积
- 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 = π * radius² (可以使用 math.pi 作为 π 的值)
- 要求:函数接收一个位置参数 radius。计算半径为5、0、-1时候的面积
- 注意点:可以采取try-except 使函数变得更加稳健,如果传入的半径为负数,函数应该返回 0 (或者可以考虑引发一个ValueError,但为了简单起见,先返回0)。
import mathdef calculate_circle_area(radius):try:if radius < 0:return 0return math.pi * radius ** 2except Exception:return 0# 计算半径为5、0、-1时候的面积
print(calculate_circle_area(5))
print(calculate_circle_area(0))
print(calculate_circle_area(-1))
题目2:计算矩形的面积
- 任务: 编写一个名为 calculate_rectangle_area 的函数,该函数接收矩形的长度 length 和宽度 width 作为参数,并返回矩形的面积。
- 公式: 矩形面积 = length * width
- 要求:函数接收两个位置参数 length 和 width。
- 函数返回计算得到的面积。
- 如果长度或宽度为负数,函数应该返回 0。
def calculate_rectangle_area(length, width):if length < 0 or width < 0:return 0return length * width
或者
def calculate_rectangle_area(length,width):try:if length >= 0 and width >= 0:area = length * widthreturn areaelse: return 0except ValueError:return 0
题目3:计算任意数量数字的平均值
- 任务: 编写一个名为 calculate_average 的函数,该函数可以接收任意数量的数字作为参数(引入可变位置参数 (*args)),并返回它们的平均值。
- 要求:使用 *args 来接收所有传入的数字。
- 如果没有任何数字传入,函数应该返回 0。
- 函数返回计算得到的平均值。
def calculate_average(*args):try:if len(args) == 0:return 0total = sum(args)average = total / len(args)return averageexcept nError:return 0
题目4:打印用户信息
- 任务: 编写一个名为 print_user_info 的函数,该函数接收一个必需的参数 user_id,以及任意数量的额外用户信息(作为关键字参数)。
- 要求:
- user_id 是一个必需的位置参数。
- 使用 **kwargs 来接收额外的用户信息。
- 函数打印出用户ID,然后逐行打印所有提供的额外信息(键和值)。
- 函数不需要返回值
def print_user_info(user_id, **kwargs):if kwargs:print("额外信息:")for key, value in kwargs.items():print(f" {key}: {value}")else:print("没有提供额外信息。")
题目5:格式化几何图形描述
- 任务: 编写一个名为 describe_shape 的函数,该函数接收图形的名称 shape_name (必需),一个可选的 color (默认 “black”),以及任意数量的描述该图形尺寸的关键字参数 (例如 radius=5 对于圆,length=10, width=4 对于矩形)。
- 要求:shape_name 是必需的位置参数。
- color 是一个可选参数,默认值为 “black”。
- 使用 **kwargs 收集描述尺寸的参数。
- 函数返回一个描述字符串,格式如下:
- “A [color] [shape_name] with dimensions: [dim1_name]=[dim1_value], [dim2_name]=[dim2_value], …”如果 **kwargs 为空,则尺寸部分为 “with no specific dimensions.”
desc1 = describe_shape("circle", radius=5, color="red")
print(desc1)
# 输出: A red circle with dimensions: radius=5desc2 = describe_shape("rectangle", length=10, width=4)
print(desc2)
# 输出: A black rectangle with dimensions: length=10, width=4desc3 = describe_shape("triangle", base=6, height=8, color="blue")
print(desc3)
# 输出: A blue triangle with dimensions: base=6, height=8desc4 = describe_shape("point", color="green")
print(desc4)
# 输出: A green point with no specific dimensions.
def describe_shape(shape_name,color,**kwargs):try:print(f"A {color} {shape_name} with the dimensions: ")for key, value in kwargs.items():print(f" {key}: {value}")except KeyError:return 0