当前位置: 首页 > news >正文

DAY 26 函数专题1:函数定义与参数-2025.9.13

DAY 26 函数专题1:函数定义与参数

知识点回顾

  1. 函数的定义
  2. 变量作用域:局部变量和全局变量
  3. 函数的参数类型:位置参数、默认参数、不定参数
  4. 传递参数的手段:关键词参数
  5. 传递参数的顺序:同时出现三种参数类型时

作业

题目1:计算圆的面积

  • 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 = π * radius² (可以使用 math.pi 作为 π 的值)
  • 要求:函数接收一个位置参数 radius。计算半径为5、0、-1时候的面积
  • 注意点:可以采取try-except 使函数变得更加稳健,如果传入的半径为负数,函数应该返回 0 (或者可以考虑引发一个ValueError,但为了简单起见,先返回0)。

题目2:计算矩形的面积

  • 任务: 编写一个名为 calculate_rectangle_area 的函数,该函数接收矩形的长度 length 和宽度 width 作为参数,并返回矩形的面积。
  • 公式: 矩形面积 = length * width
  • 要求:函数接收两个位置参数 length 和 width。
    • 函数返回计算得到的面积。
    • 如果长度或宽度为负数,函数应该返回 0。

题目3:计算任意数量数字的平均值

  • 任务: 编写一个名为 calculate_average 的函数,该函数可以接收任意数量的数字作为参数(引入可变位置参数 (*args)),并返回它们的平均值。
  • 要求:使用 *args 来接收所有传入的数字。
    • 如果没有任何数字传入,函数应该返回 0。
    • 函数返回计算得到的平均值。

题目4:打印用户信息

  • 任务: 编写一个名为 print_user_info 的函数,该函数接收一个必需的参数 user_id,以及任意数量的额外用户信息(作为关键字参数)。
  • 要求:
    • user_id 是一个必需的位置参数。
    • 使用 **kwargs 来接收额外的用户信息。
    • 函数打印出用户ID,然后逐行打印所有提供的额外信息(键和值)。
    • 函数不需要返回值

题目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.”

笔记:

1. 函数的定义:代码的 “工具模块”

函数是一段可重复使用的代码块,用来完成特定任务。定义函数就像制作一个 “工具”,需要时直接调用即可,避免重复写相同代码。

基本语法

def 函数名(参数列表):"""函数说明文档(可选)"""# 函数体(具体逻辑)return 返回值(可选)

例子:定义一个计算模型准确率的函数

def calculate_accuracy(y_true, y_pred):"""计算分类模型的准确率"""correct = sum(t == p for t, p in zip(y_true, y_pred))total = len(y_true)return correct / total if total != 0 else 0.0  # 避免除零错误

机器学习场景:在模型评估时,可重复调用这个函数计算训练集、验证集、测试集的准确率,无需重复写计算逻辑。

2. 变量作用域:变量的 “活动范围”

变量的作用域指变量能被访问的代码范围,分为两种:

类型定义位置访问范围举例
局部变量函数内部仅在定义它的函数内部可访问函数calculate_accuracy中的correcttotal
全局变量函数外部(整个程序顶层)整个程序(包括所有函数)都可访问在函数外定义的dataset_path = "data/train.csv"

注意点

  • 函数内部可以读取全局变量,但修改全局变量时需要用global声明,否则会被当作局部变量处理。
# 全局变量
learning_rate = 0.01def set_learning_rate(new_lr):# 声明要修改全局变量global learning_ratelearning_rate = new_lr  # 此时修改的是全局变量set_learning_rate(0.001)
print(learning_rate)  # 输出 0.001(全局变量已被修改)

机器学习场景:全局变量可用于存储整个程序都需要的配置(如数据路径、全局种子),局部变量用于函数内部的临时计算(如中间结果)。

3. 函数的参数类型:函数的 “输入接口”

函数的参数是调用时传入的 “原材料”,常见类型有 3 种:

(1)位置参数:必须按顺序传递的参数

最基础的参数类型,调用时必须按定义的顺序传递,且数量要与定义一致。

# 定义:位置参数x, y
def add(x, y):return x + y# 调用:必须传递2个参数,顺序对应x, y
print(add(3, 5))  # 输出8(3传给x,5传给y)

(2)默认参数:有默认值的参数

定义时给参数设定默认值,调用时可以不传递(使用默认值),也可以传递新值覆盖默认值。

# 定义:默认参数epochs(默认值10)
def train_model(X, y, epochs=10):print(f"用{epochs}轮训练模型")# 调用1:不传递epochs,使用默认值10
train_model(X_train, y_train)  # 输出"用10轮训练模型"# 调用2:传递epochs=20,覆盖默认值
train_model(X_train, y_train, 20)  # 输出"用20轮训练模型"

注意:默认参数必须放在位置参数后面(否则会报错)。

(3)不定参数:接收任意数量的参数

当不确定需要传递多少个参数时使用,有两种形式:

  • *args:接收任意数量的位置参数,返回一个元组;
  • **kwargs:接收任意数量的关键字参数(见下文),返回一个字典。
# *args示例:计算多个特征的平均值
def mean_features(*args):# args是元组,例如传入1,2,3时,args=(1,2,3)return sum(args) / len(args) if args else 0print(mean_features(1.2, 3.4, 2.1))  # 输出(1.2+3.4+2.1)/3 = 2.233...# **kwargs示例:处理模型的多个超参数
def set_hyperparameters(** kwargs):# kwargs是字典,例如传入lr=0.01, batch=32时,kwargs={"lr":0.01, "batch":32}for name, value in kwargs.items():print(f"超参数{name} = {value}")set_hyperparameters(lr=0.01, batch_size=32, epochs=50)
# 输出:
# 超参数lr = 0.01
# 超参数batch_size = 32
# 超参数epochs = 50

机器学习场景:不定参数非常适合处理可变数量的输入(如多个特征、多个超参数),例如模型集成时接收多个基础模型。

4. 传递参数的手段:关键词参数

调用函数时,通过参数名 = 值的形式传递参数,称为关键词参数。
优点:不需要严格按顺序传递,代码更易读(尤其参数较多时)。

# 定义一个包含多个参数的函数
def build_model(input_dim, hidden_dim, output_dim, activation="relu"):print(f"输入维度{input_dim},隐藏层{hidden_dim},输出{output_dim},激活函数{activation}")# 用关键词参数调用(顺序可以打乱)
build_model(hidden_dim=128,input_dim=64,activation="tanh",output_dim=10
)
# 输出:输入维度64,隐藏层128,输出10,激活函数tanh

机器学习场景:模型定义时参数往往很多(输入维度、隐藏层大小、激活函数等),用关键词参数传递能避免记混顺序,减少错误。

5. 传递参数的顺序:多种参数共存时的规则

当函数同时包含 ** 位置参数、默认参数、*args、kwargs时,定义和调用必须遵循固定顺序,否则会报错。

定义时的顺序(从左到右)

  1. 位置参数
  2. 默认参数
  3. *args(不定位置参数)
  4. **kwargs(不定关键字参数)

示例:符合顺序的函数定义

def example_func(pos1, pos2, default1=0, default2=1, *args, **kwargs):print(f"位置参数:{pos1}, {pos2}")print(f"默认参数:{default1}, {default2}")print(f"不定位置参数*args:{args}")print(f"不定关键字参数**kwargs:{kwargs}")

调用时的对应规则

  • 位置参数必须先传,且数量匹配;
  • 默认参数可传可不传,传时可按位置或关键词;
  • *args接收剩下的位置参数;
  • **kwargs接收剩下的关键词参数。
# 调用示例
example_func(10, 20,  # 位置参数pos1=10, pos2=2030,      # 默认参数default1=30(默认2=1不变)40, 50,  # 剩下的位置参数,被*args接收:args=(40,50)a=1, b=2 # 关键词参数,被**kwargs接收:kwargs={"a":1, "b":2}
)

为什么要这样规定顺序?

  • 位置参数是 “必须传递且顺序敏感” 的,放在最前;
  • 默认参数是 “可选且有默认值” 的,紧随其后;
  • *args**kwargs是 “可变数量” 的,放在最后避免歧义。

总结

  • 函数是可重用的代码块,用def定义;
  • 变量作用域分局部(函数内)和全局(函数外),修改全局变量需用global
  • 参数类型:位置参数(必传)、默认参数(有默认值)、*args(不定位置)、**kwargs(不定关键字);
  • 关键词参数通过参数名=值传递,不依赖顺序,更清晰;
    多参数共存时,定义顺序为:位置参数 → 默认参数 → *args**kwargs

这些是函数的核心基础,掌握后能写出更简洁、灵活的代码,尤其在机器学习中处理数据和模型时非常重要。

作业

题目1:计算圆的面积

  • 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 = π * radius² (可以使用 math.pi 作为 π 的值)
  • 要求:函数接收一个位置参数 radius。计算半径为5、0、-1时候的面积
  • 注意点:可以采取try-except 使函数变得更加稳健,如果传入的半径为负数,函数应该返回 0 (或者可以考虑引发一个ValueError,但为了简单起见,先返回0)。
import math def calculate_circle_area(radius):'''计算圆的面积参数:radius: 圆的半径,必须是数字类型返回:圆的面积,若半径为负数则返回0'''try: # 检查半径是否为负数if radius < 0:return 0 # 计算圆的面积:π * radius²area = math.pi * radius ** 2return areaexcept TypeError:# 处理非数字类型的输入print("错误:半径必须是数字类型")return 0# 测试不同半径的情况
print(f"半径为5的圆面积: {calculate_circle_area(5):.4f}")
print(f"半径为0的圆面积: {calculate_circle_area(0)}")
print(f"半径为-1的圆面积: {calculate_circle_area(-1)}")# 测试一个异常情况(非数字输入)
print(f"非数字输入的情况: {calculate_circle_area('invalid')}")

半径为5的圆面积: 78.5398
半径为0的圆面积: 0.0
半径为-1的圆面积: 0
错误:半径必须是数字类型
非数字输入的情况: 0


题目2:计算矩形的面积

  • 任务: 编写一个名为 calculate_rectangle_area 的函数,该函数接收矩形的长度 length 和宽度 width 作为参数,并返回矩形的面积。
  • 公式: 矩形面积 = length * width
  • 要求:函数接收两个位置参数 length 和 width。
    • 函数返回计算得到的面积。
    • 如果长度或宽度为负数,函数应该返回 0。
def calculate_rectangle_area(length,width):'''计算矩形的面积参数:length: 矩形的长度width:矩形的宽度返回:矩形的面积,若长度伙宽度为负数,则返回0'''try:if length < 0 :return 0 if width < 0 :return 0area = length * widthreturn areaexcept TypeError:# 处理非数字类型的输入print("错误:参数必须是数字类型")return 0print(f'长为4,宽为2的矩形的面积为:{calculate_rectangle_area(4,2)}')
print(f'长为0,宽为2的矩形的面积为:{calculate_rectangle_area(0,2)}')
print(f'长为4,宽为0的矩形的面积为:{calculate_rectangle_area(4,0)}')
print(f'长为-1,宽为2的矩形的面积为:{calculate_rectangle_area(-1,2)}')
print(f'长为4,宽为-1的矩形的面积为:{calculate_rectangle_area(4,-1)}')# 测试一个异常情况(非数字输入)
print(f"非数字输入的情况: {calculate_rectangle_area('4',2)}")

长为4,宽为2的矩形的面积为:8
长为0,宽为2的矩形的面积为:0
长为4,宽为0的矩形的面积为:0
长为-1,宽为2的矩形的面积为:0
长为4,宽为-1的矩形的面积为:0
错误:参数必须是数字类型
非数字输入的情况: 0


题目3:计算任意数量数字的平均值

  • 任务: 编写一个名为 calculate_average 的函数,该函数可以接收任意数量的数字作为参数(引入可变位置参数 (*args)),并返回它们的平均值。
  • 要求:使用 *args 来接收所有传入的数字。
    • 如果没有任何数字传入,函数应该返回 0。
    • 函数返回计算得到的平均值。
def calculate_average(*args):try:if len(args) == 0:return 0 total = sum(args)average = total/len(args)return averageexcept TypeError:print('错误:参数必须是数字类型')return 0 # 测试不同情况
print(f"没有参数: {calculate_average()}")  # 应该返回0
print(f"一个参数: {calculate_average(5)}")  # 应该返回5.0
print(f"多个参数: {calculate_average(1, 2, 3, 4, 5)}")  # 应该返回3.0
print(f"包含负数: {calculate_average(10, -5, 3)}")  # 应该返回(10-5+3)/3 = 8/3 ≈ 2.666...
print(f"包含浮点数: {calculate_average(2.5, 3.5, 4.0)}")  # 应该返回(2.5+3.5+4.0)/3 = 10/3 ≈ 3.333...# 测试异常情况(包含非数字)
print(f"包含非数字: {calculate_average(1, 2, 'three')}")  # 应该捕获错误并返回0

没有参数: 0
一个参数: 5.0
多个参数: 3.0
包含负数: 2.6666666666666665
包含浮点数: 3.3333333333333335
错误:参数必须是数字类型
包含非数字: 0


题目4:打印用户信息

  • 任务: 编写一个名为 print_user_info 的函数,该函数接收一个必需的参数 user_id,以及任意数量的额外用户信息(作为关键字参数)。
  • 要求:
    • user_id 是一个必需的位置参数。
    • 使用 **kwargs 来接收额外的用户信息。
    • 函数打印出用户ID,然后逐行打印所有提供的额外信息(键和值)。
    • 函数不需要返回值
def print_user_info(user_id, **kwargs):print(f'User ID :{user_id}')if kwargs:print('Additional Information:')for key, value in kwargs.items():print(f"  {key}: {value}")else:print("No additional information provided.")# 测试函数
print("测试1:只提供user_id")
print_user_info(1001)
print("\n测试2:提供user_id和基本信息")
print_user_info(1002, name="Alice", age=30, email="alice@example.com")
print("\n测试3:提供更多信息")
print_user_info(1003, name="Bob", age=25, email="bob@example.com", occupation="Data Scientist", hobbies=["reading", "hiking", "coding"]
)

测试1:只提供user_id
User ID :1001
No additional information provided.

测试2:提供user_id和基本信息
User ID :1002
Additional Information:
name: Alice
age: 30
email: alice@example.com

测试3:提供更多信息
User ID :1003
Additional Information:
name: Bob
age: 25
email: bob@example.com
occupation: Data Scientist
hobbies: [‘reading’, ‘hiking’, ‘coding’]


题目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.”
def describe_shape(shape_name, color="black", **kwargs):"""生成几何图形的描述字符串(修复参数传递问题)参数:shape_name: 必需,图形名称(位置参数)color: 可选,图形颜色,默认值为"black"**kwargs: 关键字参数,描述图形的尺寸返回:格式化的图形描述字符串"""try:# 验证参数类型if not isinstance(shape_name, str):raise TypeError("shape_name must be a string (图形名称必须是字符串)")if not isinstance(color, str):raise TypeError("color must be a string (颜色必须是字符串)")# 构建基础描述部分description = f"A {color} {shape_name} with "# 处理尺寸描述部分if kwargs:dimensions = []for dim_name, dim_value in kwargs.items():if not isinstance(dim_value, (int, float)):raise TypeError(f"Dimension {dim_name} must be a number (尺寸{dim_name}必须是数字)")dimensions.append(f"{dim_name}={dim_value}")description += f"dimensions: {', '.join(dimensions)}"else:description += "no specific dimensions."return descriptionexcept TypeError as e:return f"参数错误: {e}"except Exception as e:return f"意外错误: {e}"# 重新测试修复后的函数
print("测试1:基本用法(圆)")
print(describe_shape("circle", "red", radius=5))  # 正常传递colorprint("\n测试2:使用默认颜色(矩形)")
# 不传递color,使用默认值"black"
print(describe_shape("rectangle", length=10, width=4))  print("\n测试3:没有尺寸参数(三角形)")
print(describe_shape("triangle", "blue"))  # 传递color,无尺寸print("\n测试4:多个尺寸参数(长方体)")
print(describe_shape("cuboid", "green", length=5, width=3, height=2))print("\n测试5:异常情况(shape_name不是字符串)")
print(describe_shape(123, "yellow", radius=3))  # shape_name类型错误print("\n测试6:异常情况(尺寸不是数字)")
print(describe_shape("square", side="five"))  # 尺寸值不是数字

测试1:基本用法(圆)
A red circle with dimensions: radius=5

测试2:使用默认颜色(矩形)
A black rectangle with dimensions: length=10, width=4

测试3:没有尺寸参数(三角形)
A blue triangle with no specific dimensions.

测试4:多个尺寸参数(长方体)
A green cuboid with dimensions: length=5, width=3, height=2

测试5:异常情况(shape_name不是字符串)
参数错误: shape_name must be a string (图形名称必须是字符串)

测试6:异常情况(尺寸不是数字)
参数错误: Dimension side must be a number (尺寸side必须是数字)

@浙大疏锦行


文章转载自:

http://jwMtIIk3.kghhL.cn
http://Yy1xDQU2.kghhL.cn
http://d4QxFVhH.kghhL.cn
http://DfnF0lJT.kghhL.cn
http://LH6cg4aD.kghhL.cn
http://j8zVpQg2.kghhL.cn
http://NEDjWY7J.kghhL.cn
http://J3Hq1rz4.kghhL.cn
http://SXjnBk4L.kghhL.cn
http://V9lQrv9f.kghhL.cn
http://rWx8x8Vj.kghhL.cn
http://hTNiDlth.kghhL.cn
http://FyXFmikX.kghhL.cn
http://rxuWLCXF.kghhL.cn
http://bCGoWWi9.kghhL.cn
http://94Kz1HbC.kghhL.cn
http://F3TDrYHU.kghhL.cn
http://z9upTHgT.kghhL.cn
http://Cv5boW2k.kghhL.cn
http://gwg8FI08.kghhL.cn
http://tuSWbTAc.kghhL.cn
http://ILhIpCx4.kghhL.cn
http://ajWuyilN.kghhL.cn
http://KAe9fRWq.kghhL.cn
http://tJD7EEpk.kghhL.cn
http://fJe3taNI.kghhL.cn
http://f9LFTe1F.kghhL.cn
http://t49D2pIT.kghhL.cn
http://T7GMriOB.kghhL.cn
http://KuqMH6gz.kghhL.cn
http://www.dtcms.com/a/381050.html

相关文章:

  • MySQL的基础和进阶与运维
  • 看到手就亮灯 防夹手视觉光栅
  • QT M/V架构开发实战:M/V架构的初步认识
  • 4.2-中间件之MySQL
  • 基于hiprint的票据定位打印系统开发实践
  • 批量获取虾皮商品数据:开放API接口操作详解
  • @JsonFormat 如何在get请求中日期字段不报错还能使用
  • C/C++ 标准库中的 `strspn` 函数
  • 关闭click for mouse control
  • C语言打印爱心
  • Notion-Folder-Opener | 一个极简、稳定的本地“链接→打开文件/文件夹”工具
  • Linux系统 SELinux 安全管理与故障排查
  • Vue:后端服务代码解析
  • 仓颉语言与C++对比深度解析:从特性对比到语言选型及实践
  • 嵌入式 - ARM6
  • uniapp | 快速上手ThorUI组件
  • 容器使用绑定挂载
  • 智能排班系统哪个好?从L1到L4,AI排班软件选型指南
  • CentOS7.9 离线升级内核
  • 杨辉三角**
  • Android「Global / Secure / System」三大命名空间全局设置项总结
  • 【嵌入式】【科普】运动控制岗位相关职责
  • 期货盘后空开是认购期权行权?
  • 【一天一个Web3概念】Web3.0赛道分析:新一轮技术浪潮下的机遇与挑战
  • HMI界面设计:9个工业触摸屏原型案例合集与核心要点解析
  • 【一天一个Web3概念】从 Web1.0 到 Web3.0:互联网的三次演进与未来趋势
  • EMG肌电信号可视化系统【附源码】
  • 解读HRV与认知负荷
  • 打工人日报#20250912
  • 有度新版本:待办全新升级、企业互联、自带数据库...协作体验更佳!