Files

274 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
doc_type: short
full_text: sources/07_Functions.md
---
# 07_Functions 总结
本文介绍了 Python 程序组织的基础工具:自定义函数、标准库函数、异常处理,以及如何把脚本改造成可复用、可测试、可从命令行调用的程序。它延续前一节文件处理内容,将 `pcost.py` 逐步重构为函数式、健壮且更接近真实使用场景的程序。
## 核心内容
### 自定义函数
函数用于封装可复用代码。一个函数通常包含:
- `def` 关键字定义函数
- 参数列表接收输入
- 函数体执行任务
- `return` 显式返回结果
- 可选的文档字符串说明用途
示例:
```python
def sumcount(n):
'''
Returns the sum of the first n integers
'''
total = 0
while n > 0:
total += n
n -= 1
return total
```
调用函数:
```python
a = sumcount(100)
```
函数是组织较大程序的重要方式,也是代码复用和测试的基础。相关主题可扩展为 python functions、code reuse。
### 文档字符串
如果函数的第一条语句是字符串,它会成为函数的文档字符串,可以通过 `help()` 查看。
```python
def greeting(name):
'Issues a greeting'
print('Hello', name)
```
这体现了 Python 中“代码即文档”的轻量实践,可关联 documentation。
## 标准库函数与模块
Python 自带大型标准库,通过 `import` 使用模块中的函数和对象。
示例:
```python
import math
x = math.sqrt(10)
import urllib.request
u = urllib.request.urlopen('http://www.python.org/')
data = u.read()
```
本文只做简要介绍,后续会更深入讨论模块和库。这里强调标准库可以避免重复造轮子,是 Python 实用性的核心来源之一。相关主题:python standard library、modules and imports。
## 错误与异常
函数通过异常报告错误。未处理的异常会中断函数执行,甚至导致整个程序停止。
示例:
```python
>>> int('N/A')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'N/A'
```
异常信息通常包含:
- 发生了什么错误
- 错误发生的位置
- traceback,即导致错误的一系列函数调用路径
这些信息对调试非常重要。相关主题:python exceptions、debugging。
## 捕获和处理异常
异常可以用 `try-except` 捕获并处理。
```python
for line in file:
fields = line.split(',')
try:
shares = int(fields[1])
except ValueError:
print("Couldn't parse", line)
```
要注意:`except` 后的异常名称必须匹配实际可能发生的错误类型,例如 `ValueError`。
本文指出,在实际编程中,很难提前知道所有可能发生的错误。异常处理经常是在程序崩溃后补充的,即发现“忘了处理某类错误”之后再修正。相关主题:error handling、robust programming。
## 抛出异常
可以用 `raise` 主动抛出异常。
```python
raise RuntimeError('What a kerfuffle')
```
如果没有被 `try-except` 捕获,程序会终止并显示 traceback。
这说明异常不仅是系统自动产生的错误机制,也可以作为程序设计中的显式错误报告工具。相关主题:exception raising。
## 练习与实践路径
### 练习 1.29:定义函数
要求定义简单的 `greeting(name)` 函数,理解:
- 函数定义
- 参数传递
- 函数调用
- 文档字符串
- `help()` 查看函数说明
### 练习 1.30:把脚本改造成函数
将前一节中的 `pcost.py` 脚本改造成:
```python
def portfolio_cost(filename):
...
```
该函数接收文件名,读取投资组合数据,并返回总成本。
示例调用:
```python
cost = portfolio_cost('Data/portfolio.csv')
print('Total cost:', cost)
```
还可以通过交互模式测试:
```bash
python3 -i pcost.py
```
然后调用:
```python
>>> portfolio_cost('Data/portfolio.csv')
44671.15
```
这一练习强调:将脚本逻辑封装为函数后,代码更容易测试、复用和调试。相关主题:script to function、interactive testing。
### 练习 1.31:错误处理
当输入文件包含缺失字段时,程序可能崩溃:
```python
ValueError: invalid literal for int() with base 10: ''
```
练习要求修改 `pcost.py`:
- 捕获异常
- 打印警告信息
- 跳过坏数据行
- 继续处理剩余文件
这里引入了处理脏数据的两种策略:
1. 清理原始输入文件
2. 修改程序,使其能容忍并处理坏数据
这与现实数据处理高度相关,可关联 data cleaning、fault tolerance。
### 练习 1.32:使用 `csv` 标准库
推荐使用 Python 的 `csv` 模块处理 CSV 文件,而不是手动 `split(',')`。
示例:
```python
import csv
f = open('Data/portfolio.csv')
rows = csv.reader(f)
headers = next(rows)
```
`csv` 模块可以处理许多底层细节,例如:
- 正确拆分逗号分隔字段
- 处理引号
- 去除字段中的双引号
- 更可靠地解析 CSV 数据
这体现了使用标准库替代手写解析逻辑的价值。相关主题:csv processing、data parsing。
### 练习 1.33:从命令行读取参数
原始程序中输入文件名被硬编码:
```python
cost = portfolio_cost('Data/portfolio.csv')
```
练习要求改用 `sys.argv` 从命令行获取参数:
```python
import sys
if len(sys.argv) == 2:
filename = sys.argv[1]
else:
filename = 'Data/portfolio.csv'
cost = portfolio_cost(filename)
print('Total cost:', cost)
```
`sys.argv` 是命令行参数列表。这样程序既可以使用默认文件,也可以由用户指定输入文件。
运行方式:
```bash
python3 pcost.py Data/portfolio.csv
```
这一节把程序从“学习用脚本”推进到“可配置命令行工具”的形式。相关主题:command line arguments、python scripts。
## 关键思想
- 函数是组织、复用和测试代码的基本单位。
- `return` 用于明确给出函数结果。
- 文档字符串让函数具备内置说明。
- Python 标准库提供大量现成工具,应该优先使用。
- 异常是 Python 中报告和处理错误的主要机制。
- `try-except` 可以让程序在遇到坏数据时继续运行。
- `raise` 可以主动报告程序中的异常状态。
- 将脚本逻辑封装为函数后,可以更方便地交互测试。
- 使用 `csv` 模块比手动拆分 CSV 文本更可靠。
- 使用 `sys.argv` 可以让脚本接收命令行参数,减少硬编码。
## 与前后内容的关系
本文承接 [[summaries/06_Files]] 中的文件读取和投资组合成本计算示例,将其进一步封装为函数,并加入错误处理、标准库解析和命令行参数。它也为后续“处理数据”部分打下基础,尤其是围绕 CSV 文件、异常数据、可复用程序结构等主题。
## Related Concepts
- [[concepts/命令行参数]]
- [[concepts/函数]]
- [[concepts/异常处理]]
- [[concepts/CSV-数据处理]]
- [[concepts/模块与-import]]
- [[concepts/main-函数与脚本结构]]
- [[concepts/文件读写]]
- [[concepts/Python-交互式解释器]]
- [[concepts/Python-文档与帮助系统]]
- [[concepts/测试-日志与调试]]
- [[concepts/字符串处理]]
- [[concepts/Python-输入输出]]