Contents|上一个(1.6个文件)|Next(2.0WorkingwithData)1.7函数随着程序开始变大,我们希望以有序的方式组织它们。本节简要介绍函数、库模块和异常错误处理。自定义函数将函数用于您要重用的代码。下面是该函数的定义方式:defsumcount(n):'''返回前n个整数的总和'''total=0whilen>0:total+=nn-=1returntotalfunctioncall:a=sumcount(100)函数是执行某些任务并返回结果的一系列语句。return关键字需要显式指定函数的返回值。库函数Python自带一个庞大的标准库。使用import访问库模块。示例:importmathx=math.sqrt(10)importurllib.requestu=urllib.request.urlopen('http://www.python.org/')data=u.read()稍后我们会详细介绍库和模块。错误和异常函数将错误报告为异常。异常会导致函数中止,如果不加以处理,可能会导致整个程序终止。在你的Python解释器(REPL)中试试这个:>>>int('N/A')Traceback(mostrecentcalllast):File"",line1,inValueError:invalidliteralforint()withbase10:'N/A'>>>出于调试目的,上述错误消息描述了发生的情况、错误发生的位置以及回溯。回溯显示导致失败的其他函数调用。捕获和处理异常异常可以被捕获和处理。要捕获异常,请使用try-except语句:forlineinf:fields=line.split()try:shares=int(fields[1])exceptValueError:print("Couldn'tparse",line)...名称ValueError必须与您试图捕获的错误类型相匹配。通常,很难根据所执行的操作事先准确知道可能会发生哪种错误。不管是好是坏,在程序意外崩溃后添加异常处理是很常见的(例如:“天哪,我们忘了捕获错误。我们应该处理错误。”)。引发异常要引发异常,请使用raise语句:raiseRuntimeError('Whatakerfuffle')这将导致程序中止并出现异常回溯,除非异常被try-except代码块捕获。%python3foo.pyTraceback(最近调用最后一次):文件“foo.py”,第21行,在中raiseRuntimeError("Whatakerfuffle")RuntimeError:WhatakerfuffleExercise练习1.29:DefiningafunctionAttempttodefine一个简单的函数:>>>defgreeting(name):'Issuesagreeting'print('Hello',name)>>>greeting('Guido')HelloGuido>>>greeting('Paula')HelloPaula>>>如果函数的第一条语句是字符串,则将其视为文档字符串。尝试输入命令来显示文档字符串,例如help(greeting)。练习1.30:将脚本转换为函数将您在练习1.27中为pcost.py程序编写的代码放入portfolio_cost(filename)函数中。此函数将文件名作为输入,从文件中读取投资组合数据,并以浮点数形式返回投资组合总费用。要使用您的函数,请将程序修改为如下所示:defportfolio_cost(filename):...#Yourcodehere...cost=portfolio_cost('Data/portfolio.csv')print('Totalcost:',cost)你应该看到和以前一样的输出。运行程序后,您还可以通过键入以下内容以交互方式调用该函数:bash$python3-ipcost.py这将允许您从交互模式调用该函数:>>>portfolio_cost('Data/portfolio.csv')44671.15>>>能够以交互方式试验代码对于调试和测试非常有用。练习1.31:错误处理如果对缺少某些字段的文件使用函数会怎样?>>>portfolio_cost('Data/missing.csv')Traceback(最近调用last):文件“”,第1行,在文件“pcost.py”,第11行,inportfolio_costnshares=int(fields[1])ValueError:invalidliteralforint()withbase10:''>>>此时,您面临一个决定:要使程序正常运行,您可以消除坏行要么清理原始输入文件,或修改代码以某种方式处理错误行。修改pcost.py程序以捕获异常、打印警告消息并继续处理文件的其余部分。练习1.32:使用库函数Python带有一个包含许多有用函数的大型标准库。csv模块是一个库,在这里可能会有用。无论何时,只要必须使用CSV数据文件,就应该使用csv模块。以下是csv模块如何工作的示例:>>>importcsv>>>f=open('Data/portfolio.csv')>>>rows=csv.reader(f)>>>headers=next(rows)>>>headers['name','shares','price']>>>forrowinrows:print(row)['AA','100','32.20']['IBM','50','91.10']['CAT','150','83.44']['MSFT','200','51.23']['GE','95','40.37']['MSFT','50','65.10']['IBM','100','70.44']>>>f.close()>>>csv模块有一个很好的特性——它处理各种底层细节,例如引号和适当的逗号分隔。在上面的输出中,您会注意到它从第一列的名称中删除了双引号。修改您的pcost.py程序以使用csv模块进行解析,然后尝试运行前面的示例。练习1.33:从命令行读取在pcost.py程序中,输入文件的名称已被硬编码到代码中:#pcost.pydefportfolio_cost(filename):...#Yourcodehere...cost=portfolio_cost('Data/portfolio.csv')print('Totalcost:',cost)用于学习和测试是可以的,但在实际程序中,你可能不会这样做。相反,您可以将文件名作为参数传递给脚本。尝试按如下方式修改程序的底部:#pcost.pyimportsysdefportfolio_cost(filename):...#Yourcodehere...iflen(sys.argv)==2:filename=sys.argv[1]else:filename='Data/portfolio.csv'cost=portfolio_cost(filename)print('Totalcost:',cost)sys.argv是包含在命令行上传递的参数的列表,如果有的话。要运行该程序,您需要从终端运行Python。例如,在Unix系统上从bash运行:bash%python3pcost.pyData/portfolio.csvTotalcost:44671.15bash%directory|上一节(1.6文件)|下一节(2.0处理数据)|上一节(1.6文档)|下一节(2.0处理数据)注:完整翻译见https://github.com/codists/practical-python-zh