查看全课大纲(第 11 / 51 节)
- 1.为什么人人都该学点编程?
- 2.计算机与程序设计:你的电脑到底在“想”什么?
- 3.Python 这门语言,到底有什么魔力?
- 4.Python 开发环境配置:如何拥有你的第一个“编程工具箱”?
- 5.如何安装一个更强大的代码编辑器?
- 6.汇率兑换1.0:你的第一个“钱生钱”小程序
- 7.你的第一行代码,藏着哪些秘密?
- 8.汇率兑换2.0(上):让程序看懂“CNY”和“USD”
- 9.汇率兑换程序,如何让它“聪明”地判断币种?
- 10.汇率兑换程序能一直运行,直到我喊停吗?
- 11.汇率兑换4.0:如何把“算钱”功能打包成积木?
- 12.汇率兑换5.0:给你的程序穿上“结构化”的西装
- 13.怎么用 Python 画一个会动的五角星?
- 14.如何让程序自动画出不同大小的五角星?
- 15.函数自己调用自己,会发生什么?
- 16.用递归画出神奇的分形树
- 17.Python 怎么计算你一天躺着不动能消耗多少热量?
- 18.如何让程序“活”起来,持续为你服务?
- 19.如何让 BMR 计算器更“聪明”?
- 20.当程序遇到“不按套路出牌”的用户怎么办?
- 21.怎么用 Python 模拟一个“滚雪球”式的存钱计划?
- 22.如何用列表记录每一周的存款?
- 23.如何让程序自己数数?—— 用 for 循环解放你的双手
- 24.52周存钱挑战4.0:你的存款计算器能有多灵活?
- 25.52周存钱挑战:怎么根据日期自动查存款?
- 26.Python 怎么判断一年中的第几天?
- 27.列表 vs 元组:哪个更适合存储月份天数?
- 28.用集合给月份分个队,换个思路算天数
- 29.把月份和天数“锁”在一起:用字典给数据配个对
- 30.Python 怎么判断密码强弱?
- 31.Python 怎么给密码设置“防沉迷”系统?
- 32.Python 怎么把密码保存到文件里?
- 33.Python 怎么读取文件里的密码?
- 34.Python 怎么把密码检查工具“打包”起来?
- 35.Python 怎么把文件操作也“打包”起来?
- 36.计算机怎么“扔骰子”?——用Python模拟随机事件
- 37.如何用 Python 模拟掷两个骰子?
- 38.怎么用 Python 把骰子轨迹画出来?
- 39.骰子点数分布长啥样?用直方图一眼看穿!
- 40.用科学计算库让骰子程序“起飞”
- 41.空气质量指数怎么算?手把手教你写一个AQI计算器
- 42.空气质量指数计算:从零开始,让程序看懂空气
- 43.如何读取空气质量数据文件并找出空气质量最好的五个监测点?
- 44.JSON 数据怎么变成 Excel 表格?—— 让数据换个“马甲”
- 45.Python 怎么让程序自己判断文件类型?
- 46.如何让程序自己上网查空气质量?
- 47.用美味的汤来解析网页:Beautiful Soup 入门
- 48.如何让爬虫自动抓取全国所有城市的空气质量?
- 49.爬到的数据怎么存下来?—— 把全国空气质量数据保存为CSV文件
- 50.用 pandas 玩转空气质量数据:找出全国空气最好和最差的城市
- 51.空气质量数据怎么“洗”干净,还能画成图?
汇率兑换4.0:如何把“算钱”功能打包成积木?
约 21 分钟
小象实战讲义 · Python 入门:8 个小项目边玩边学
欢迎回来!在上一节,我们给汇率兑换程序装上了“循环引擎”,让它能一直工作,直到你喊停。现在,我们的程序已经挺能干了。但你想过没有,如果以后我们想做一个“多国货币大乱斗”的兑换器,或者想把“算钱”这个功能用在别的程序里,难道要把同样的代码再抄一遍吗?
本节我们只做一件事:把“汇率换算”这个核心功能,打包成一个可以随时调用的“积木块”——也就是函数。 学完这一节,你的程序会变得更整洁、更专业,就像把一堆散乱的乐高零件,组装成了一个随时可以拿起来用的“轮子”模块。
💡 核心导读
- 函数是什么? 一个可以重复使用的“代码积木”。
- 为什么要用函数? 让程序更清晰、更易读,避免重复劳动。
- 怎么定义函数? 用
def关键字,给它起个名字,告诉它需要什么“材料”(参数),以及它要“吐出”什么结果(返回值)。 - 怎么使用函数? 就像使用
print()和input()一样,写上函数名,把“材料”放进括号里。 - 实参和形参: 调用时给的是“实际材料”(实参),函数定义时接收的是“形式上的容器”(形参)。
一、函数:你的第一个“代码积木”
想象一下,你正在搭一个乐高城堡。你不会每次都去袋子里找单个的小砖块来拼一面墙,而是会先拼好一个“窗户模块”或者“门模块”,然后直接把这些模块装到城堡上。
函数就是程序里的“模块”。 它把一段实现特定功能的代码(比如“算钱”)打包起来,起个名字。以后想用这个功能时,不用再把那几行代码重写一遍,直接喊它的名字就行。
我们其实早就用过函数了!print()、input()、eval() 都是 Python 内置好的“积木块”。它们的特点是名字后面都跟着一对括号 ()。
在数学里,函数是 y = f(x)。x 是输入,f 是处理过程,y 是输出。编程里的函数一模一样:
- 输入:传给函数的数据(叫参数)。
- 处理:函数内部的一堆操作。
- 输出:函数计算完返回的结果(叫返回值)。
二、动手:把“算钱”装进函数
理论说再多,不如动手搭一个。我们这就来把汇率兑换的核心计算逻辑,封装成一个函数。
本节新增功能: 定义一个名为 convert_currency 的函数,专门负责金额乘以汇率。
我们先看看4.0版本完整的、可以直接运行的代码。为了让你能直接复制运行看到效果,我们把原来需要 input() 输入的地方,暂时用一个固定的字符串 '100CNY' 来代替。你可以在运行后,自己修改这个值来测试。
"""
作者:小象
功能:汇率兑换
版本:4.0
2.0 新增功能:根据输入判断是人民币还是美元,进行相应的转换计算
3.0 增加功能:程序可以一直运行,直到用户选择退出
4.0 增加功能:将汇率兑换功能封装到函数中
"""
# 1. 定义汇率兑换函数
def convert_currency(in_money, exchange_rate):
"""
汇率兑换函数
参数:
in_money: 待兑换的金额(数字)
exchange_rate: 汇率(数字)
返回值:
兑换后的金额(数字)
"""
out_money = in_money * exchange_rate # 核心计算:金额 × 汇率
return out_money # 把计算结果"吐"出去
# 2. 主程序逻辑(模块级直跑,方便你直接复制运行)
# 汇率常量
USD_VS_RMB = 6.77
# 原程序这里用 input('请输入带单位的货币金额:') 让用户输入,例如"100CNY"
# 为了让你能直接复制运行看结果,这里先用一个固定值代替,你可以改成'50USD'等测试
currency_str_value = '100CNY'
# 提取货币单位(最后3个字符)
unit = currency_str_value[-3:]
# 根据单位判断使用哪个汇率
if unit == 'CNY':
# 人民币兑美元,汇率取倒数
exchange_rate = 1 / USD_VS_RMB
elif unit == 'USD':
# 美元兑人民币,直接用原汇率
exchange_rate = USD_VS_RMB
else:
# 不支持的单位,用-1标记
exchange_rate = -1
# 3. 如果汇率有效(不是-1),则进行兑换
if exchange_rate != -1:
# 提取金额部分(去掉最后3个单位字符),并转换为数字
# 注意:这里我们用更安全的 float() 来转换,原课后面会讲到 eval() 的危险性
in_money = float(currency_str_value[:-3])
# 4. 调用函数!这是本节的核心动作
# 把 in_money 和 exchange_rate 这两个"实际材料"传给函数
out_money = convert_currency(in_money, exchange_rate)
print('转换后的金额:', out_money)
else:
print('不支持该种货币!')运行上面的代码,你会立刻看到输出:
转换后的金额: 14.771048744460858它计算了100元人民币可以兑换多少美元。
代码解读:函数的“诞生”与“召唤”
- 定义函数(造积木):
def convert_currency(in_money, exchange_rate):
out_money = in_money * exchange_rate
return out_money- `def` 是“定义”的缩写,告诉Python:“我要造一个新积木!”
- `convert_currency` 是我们给这个积木起的名字,要见名知意。
- `(in_money, exchange_rate)` 是**形参列表**,可以理解为函数工作时需要的两个“空容器”。现在它们是空的,等调用时再把实际数据装进来。
- 冒号 `:` 和缩进表示下面的代码都属于这个函数**内部**。
- `return out_money` 是函数的“出口”,它把计算好的 `out_money` 结果“返回”给调用它的地方。2. 调用函数(用积木):
def convert_currency(in_money, exchange_rate):
"""
汇率兑换函数
参数:
in_money: 待兑换的金额(数字)
exchange_rate: 汇率(数字)
返回值:
兑换后的金额(数字)
"""
out_money = in_money * exchange_rate # 核心计算:金额 × 汇率
return out_money # 把计算结果"吐"出去
# 2. 主程序逻辑(模块级直跑,方便你直接复制运行)
# 汇率常量
USD_VS_RMB = 6.77
# 原程序这里用 input('请输入带单位的货币金额:') 让用户输入,例如"100CNY"
# 为了让你能直接复制运行看结果,这里先用一个固定值代替,你可以改成'50USD'等测试
currency_str_value = '100CNY'
# 提取货币单位(最后3个字符)
unit = currency_str_value[-3:]
# 根据单位判断使用哪个汇率
if unit == 'CNY':
# 人民币兑美元,汇率取倒数
exchange_rate = 1 / USD_VS_RMB
elif unit == 'USD':
# 美元兑人民币,直接用原汇率
exchange_rate = USD_VS_RMB
else:
# 不支持的单位,用-1标记
exchange_rate = -1
# 3. 如果汇率有效(不是-1),则进行兑换
if exchange_rate != -1:
# 提取金额部分(去掉最后3个单位字符),并转换为数字
# 注意:这里我们用更安全的 float() 来转换,原课后面会讲到 eval() 的危险性
in_money = float(currency_str_value[:-3])
# 4. 调用函数!这是本节的核心动作
# 把 in_money 和 exchange_rate 这两个"实际材料"传给函数
out_money = convert_currency(in_money, exchange_rate)
print('转换后的金额:', out_money)
else:
print('不支持该种货币!')转换后的金额: 14.771048744460858- `convert_currency(in_money, exchange_rate)` 就是在“召唤”这个函数。
- 我们把 `in_money` (100) 和 `exchange_rate` (1/6.77) 这两个**实参**,按顺序填进括号里。
- 函数被“召唤”后,会暂停主程序的执行,“跳进”函数内部去计算。
- 计算完后,`return` 语句会把结果“扔回来”,我们用 `=` 赋值给变量 `out_money` 来接住它。
- 然后,主程序从刚才暂停的地方继续往下执行,打印出结果。一个生动的比喻:函数就像一个自动售货机(定义好了)。你(主程序)投进去硬币和选择按钮(传入实参),机器内部哗啦啦运转(执行函数体),最后从出货口掉出一瓶饮料(返回值),你伸手接住(用变量接收)。
三、理解函数的执行流程:一次“穿越”
让我们用调试的视角,看看当你运行程序时,计算机的“注意力”是怎么在函数内外跳跃的:
- 程序启动,从最上面开始执行。遇到
def ...时,它只是记住有这么一个函数叫convert_currency,但不会执行里面的代码。就像你看乐高说明书,先看到了“轮子模块”的图纸,但还没拼它。 - 继续往下,执行主逻辑:设置汇率、处理输入字符串、判断单位、计算
exchange_rate。 - 执行到
out_money = convert_currency(in_money, exchange_rate)这一行。 - “穿越”开始:程序暂停在这里,“跳进”
convert_currency函数内部。 - 参数传递:函数内部的“空容器”
in_money和exchange_rate被填入了外部传进来的实际值(100 和 0.1477…)。 - 内部计算:执行
out_money = in_money * exchange_rate,得到结果。 - “穿越”返回:执行
return out_money,带着计算结果“跳回”主程序刚才暂停的那一行。 - 结果接收:返回值被赋给主程序的变量
out_money。 - 继续执行:主程序接着执行
print语句,输出结果。
这个过程保证了函数可以独立工作,不干扰主程序的其他部分。
四、关于参数:实参与形参
你可能听到两个词:实参(Actual Parameter) 和 形参(Formal Parameter)。
- 形参:函数定义时括号里的
in_money, exchange_rate。它们是“形式上的参数”,是函数内部使用的变量名,是空容器。 - 实参:函数调用时括号里的
in_money, exchange_rate。它们是“实际的参数”,是调用时具体传进去的数据值。
调用时,实参的值会按顺序传递给形参。所以 convert_currency(a, b) 调用时,a 的值会给函数内的 in_money,b 的值会给函数内的 exchange_rate。
对于初学者,你只需要记住:定义函数时写的是形参(名字),调用函数时传的是实参(具体值)。它们大多数时候名字可以一样,但代表的意义不同。
📝 动手练一练
函数初体验:尝试修改代码开头的
currency_str_value = '100CNY',将其改为'50USD',再次运行程序。观察输出,理解函数是如何处理不同输入并给出正确结果的。打造新积木:假设我们还想增加一个功能,在输出金额时,固定显示两位小数(不足补零,如
338.50)。请你尝试编写一个名为format_money的函数,它接收一个数字参数,返回一个固定两位小数的字符串(提示:用 f-string 的:.2f格式最直接)。
👉 点击查看第2题参考答案
思路:我们需要一个新函数,它只做一件事:把数字格式化成固定两位小数。
关键代码片段:
def format_money(value):
"""将金额格式化为固定两位小数的字符串"""
return f'{value:.2f}' # 固定两位小数,不足位补 0(338.5 -> '338.50')
# 在主程序调用 convert_currency 获得结果后,可以这样用:
# out_money = convert_currency(in_money, exchange_rate)
# pretty_output = format_money(out_money)
# print('转换后的金额:', pretty_output)小坑提醒:题目如果只要求“四舍五入到两位”,
round(value, 2)是对的;但str(round(338.5, 2))得到的是'338.5',不会补末尾的 0。要“固定显示两位小数”,得用f'{value:.2f}'。
你可以把这个函数定义加到前面的完整程序里,并修改打印部分来使用它。试试看!
- 思维挑战:如果我们想把整个货币判断和计算流程(从输入字符串到输出结果)都打包成一个函数,比如叫
currency_converter(currency_str),你觉得这个函数需要几个参数?它的内部结构大概会是怎样的?
👉 点击查看思路提示
这个函数的目标是“一键兑换”。所以它只需要一个参数:带单位的货币字符串(如 '100CNY')。
函数内部需要包含我们目前主程序里的所有逻辑:
- 定义常量汇率
USD_VS_RMB。 - 提取单位
unit。 - 根据
unit判断并计算exchange_rate。 - 提取金额并转换为数字
in_money。 - 计算
out_money = in_money * exchange_rate。 - 用
return out_money返回最终结果。
这样,在其他地方我们只需要写 result = currency_converter('100CNY') 就能得到结果,非常简洁!这就是函数封装的魅力——隐藏复杂细节,提供简单接口。
本章小结
恭喜!你刚刚掌握了编程中一个极其重要的概念——函数。你不再只是使用别人写好的 print,而是亲手创建了自己的第一个功能模块 convert_currency。
函数的核心价值:
- 复用:一次编写,多次调用,告别复制粘贴。
- 模块化:把复杂程序拆分成一个个小功能块,结构清晰,易于理解和维护。
- 隐藏复杂性:使用者只需要知道“函数能干什么”,不需要关心“函数内部怎么干”。
📋 行动清单
- 运行并修改本节提供的完整代码,分别测试
‘100CNY’和‘50USD’的输入,确保你理解函数的调用过程。 - 尝试挑战“动手练一练”中的第2题,亲手打造一个
format_money函数,感受创建函数的乐趣。 - 思考一下:你目前生活中或工作里,有哪些重复性的任务或计算,可以用一个简单的函数来描述?试着用中文写下它的“输入”和“输出”。
我们的汇率兑换程序已经越来越像样了。下一节,我们将探索让这个函数变得更简洁、更优雅的写法,并学习如何更好地组织整个程序的结构。敬请期待!
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载第2章代码包:汇率兑换(含全部版本 5 个 .py)ZIP · 3KB