查看全课大纲(第 11 / 51 节)
  1. 1.为什么人人都该学点编程?
  2. 2.计算机与程序设计:你的电脑到底在“想”什么?
  3. 3.Python 这门语言,到底有什么魔力?
  4. 4.Python 开发环境配置:如何拥有你的第一个“编程工具箱”?
  5. 5.如何安装一个更强大的代码编辑器?
  6. 6.汇率兑换1.0:你的第一个“钱生钱”小程序
  7. 7.你的第一行代码,藏着哪些秘密?
  8. 8.汇率兑换2.0(上):让程序看懂“CNY”和“USD”
  9. 9.汇率兑换程序,如何让它“聪明”地判断币种?
  10. 10.汇率兑换程序能一直运行,直到我喊停吗?
  11. 11.汇率兑换4.0:如何把“算钱”功能打包成积木?
  12. 12.汇率兑换5.0:给你的程序穿上“结构化”的西装
  13. 13.怎么用 Python 画一个会动的五角星?
  14. 14.如何让程序自动画出不同大小的五角星?
  15. 15.函数自己调用自己,会发生什么?
  16. 16.用递归画出神奇的分形树
  17. 17.Python 怎么计算你一天躺着不动能消耗多少热量?
  18. 18.如何让程序“活”起来,持续为你服务?
  19. 19.如何让 BMR 计算器更“聪明”?
  20. 20.当程序遇到“不按套路出牌”的用户怎么办?
  21. 21.怎么用 Python 模拟一个“滚雪球”式的存钱计划?
  22. 22.如何用列表记录每一周的存款?
  23. 23.如何让程序自己数数?—— 用 for 循环解放你的双手
  24. 24.52周存钱挑战4.0:你的存款计算器能有多灵活?
  25. 25.52周存钱挑战:怎么根据日期自动查存款?
  26. 26.Python 怎么判断一年中的第几天?
  27. 27.列表 vs 元组:哪个更适合存储月份天数?
  28. 28.用集合给月份分个队,换个思路算天数
  29. 29.把月份和天数“锁”在一起:用字典给数据配个对
  30. 30.Python 怎么判断密码强弱?
  31. 31.Python 怎么给密码设置“防沉迷”系统?
  32. 32.Python 怎么把密码保存到文件里?
  33. 33.Python 怎么读取文件里的密码?
  34. 34.Python 怎么把密码检查工具“打包”起来?
  35. 35.Python 怎么把文件操作也“打包”起来?
  36. 36.计算机怎么“扔骰子”?——用Python模拟随机事件
  37. 37.如何用 Python 模拟掷两个骰子?
  38. 38.怎么用 Python 把骰子轨迹画出来?
  39. 39.骰子点数分布长啥样?用直方图一眼看穿!
  40. 40.用科学计算库让骰子程序“起飞”
  41. 41.空气质量指数怎么算?手把手教你写一个AQI计算器
  42. 42.空气质量指数计算:从零开始,让程序看懂空气
  43. 43.如何读取空气质量数据文件并找出空气质量最好的五个监测点?
  44. 44.JSON 数据怎么变成 Excel 表格?—— 让数据换个“马甲”
  45. 45.Python 怎么让程序自己判断文件类型?
  46. 46.如何让程序自己上网查空气质量?
  47. 47.用美味的汤来解析网页:Beautiful Soup 入门
  48. 48.如何让爬虫自动抓取全国所有城市的空气质量?
  49. 49.爬到的数据怎么存下来?—— 把全国空气质量数据保存为CSV文件
  50. 50.用 pandas 玩转空气质量数据:找出全国空气最好和最差的城市
  51. 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元人民币可以兑换多少美元。

代码解读:函数的“诞生”与“召唤”

  1. 定义函数(造积木):
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` 来接住它。
- 然后,主程序从刚才暂停的地方继续往下执行,打印出结果。

一个生动的比喻:函数就像一个自动售货机(定义好了)。你(主程序)投进去硬币和选择按钮(传入实参),机器内部哗啦啦运转(执行函数体),最后从出货口掉出一瓶饮料(返回值),你伸手接住(用变量接收)。

三、理解函数的执行流程:一次“穿越”

让我们用调试的视角,看看当你运行程序时,计算机的“注意力”是怎么在函数内外跳跃的:

  1. 程序启动,从最上面开始执行。遇到 def ... 时,它只是记住有这么一个函数叫 convert_currency,但不会执行里面的代码。就像你看乐高说明书,先看到了“轮子模块”的图纸,但还没拼它。
  2. 继续往下,执行主逻辑:设置汇率、处理输入字符串、判断单位、计算 exchange_rate。
  3. 执行到 out_money = convert_currency(in_money, exchange_rate) 这一行。
  4. “穿越”开始:程序暂停在这里,“跳进” convert_currency 函数内部。
  5. 参数传递:函数内部的“空容器” in_money 和 exchange_rate 被填入了外部传进来的实际值(100 和 0.1477…)。
  6. 内部计算:执行 out_money = in_money * exchange_rate,得到结果。
  7. “穿越”返回:执行 return out_money,带着计算结果“跳回”主程序刚才暂停的那一行。
  8. 结果接收:返回值被赋给主程序的变量 out_money。
  9. 继续执行:主程序接着执行 print 语句,输出结果。

这个过程保证了函数可以独立工作,不干扰主程序的其他部分。

四、关于参数:实参与形参

你可能听到两个词:实参(Actual Parameter) 和 形参(Formal Parameter)。

  • 形参:函数定义时括号里的 in_money, exchange_rate。它们是“形式上的参数”,是函数内部使用的变量名,是空容器。
  • 实参:函数调用时括号里的 in_money, exchange_rate。它们是“实际的参数”,是调用时具体传进去的数据值。

调用时,实参的值会按顺序传递给形参。所以 convert_currency(a, b) 调用时,a 的值会给函数内的 in_money,b 的值会给函数内的 exchange_rate。

对于初学者,你只需要记住:定义函数时写的是形参(名字),调用函数时传的是实参(具体值)。它们大多数时候名字可以一样,但代表的意义不同。


📝 动手练一练

  1. 函数初体验:尝试修改代码开头的 currency_str_value = '100CNY',将其改为 '50USD',再次运行程序。观察输出,理解函数是如何处理不同输入并给出正确结果的。

  2. 打造新积木:假设我们还想增加一个功能,在输出金额时,固定显示两位小数(不足补零,如 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}'。

你可以把这个函数定义加到前面的完整程序里,并修改打印部分来使用它。试试看!

  1. 思维挑战:如果我们想把整个货币判断和计算流程(从输入字符串到输出结果)都打包成一个函数,比如叫 currency_converter(currency_str),你觉得这个函数需要几个参数?它的内部结构大概会是怎样的?
👉 点击查看思路提示

这个函数的目标是“一键兑换”。所以它只需要一个参数:带单位的货币字符串(如 '100CNY')。

函数内部需要包含我们目前主程序里的所有逻辑:

  1. 定义常量汇率 USD_VS_RMB。
  2. 提取单位 unit。
  3. 根据 unit 判断并计算 exchange_rate。
  4. 提取金额并转换为数字 in_money。
  5. 计算 out_money = in_money * exchange_rate。
  6. 用 return out_money 返回最终结果。

这样,在其他地方我们只需要写 result = currency_converter('100CNY') 就能得到结果,非常简洁!这就是函数封装的魅力——隐藏复杂细节,提供简单接口。


本章小结

恭喜!你刚刚掌握了编程中一个极其重要的概念——函数。你不再只是使用别人写好的 print,而是亲手创建了自己的第一个功能模块 convert_currency。

函数的核心价值:

  • 复用:一次编写,多次调用,告别复制粘贴。
  • 模块化:把复杂程序拆分成一个个小功能块,结构清晰,易于理解和维护。
  • 隐藏复杂性:使用者只需要知道“函数能干什么”,不需要关心“函数内部怎么干”。

📋 行动清单

  • 运行并修改本节提供的完整代码,分别测试 ‘100CNY’ 和 ‘50USD’ 的输入,确保你理解函数的调用过程。
  • 尝试挑战“动手练一练”中的第2题,亲手打造一个 format_money 函数,感受创建函数的乐趣。
  • 思考一下:你目前生活中或工作里,有哪些重复性的任务或计算,可以用一个简单的函数来描述?试着用中文写下它的“输入”和“输出”。

我们的汇率兑换程序已经越来越像样了。下一节,我们将探索让这个函数变得更简洁、更优雅的写法,并学习如何更好地组织整个程序的结构。敬请期待!

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第2章代码包:汇率兑换(含全部版本 5 个 .py)
    ZIP · 3KB
    下载
看图文没弄懂?展开看本节视频讲解(约 21 分钟)
📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)