翻译:《实用的 Python 编程》01_07_Functions - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
codists
V2EX    Python

翻译:《实用的 Python 编程》01_07_Functions

  •  1
     
  •   codists
    codists 2021-02-19 12:55:19 +08:00 1332 次点击
    这是一个创建于 1700 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1.7 函数

    随着程序开始变大,我们会想要有条理地组织这些程序。本节简要介绍函数、库模块以及带有异常的错误处理。

    自定义函数

    对你要重用的代码使用函数。下面是函数的定义方式:

    def sumcount(n): ''' Returns the sum of the first n integers ''' total = 0 while n > 0: total += n n -= 1 return total 

    函数调用:

    a = sumcount(100) 

    函数是执行某些任务并返回结果的一系列语句。 return 关键字需要显式指定函数的返回值。

    库函数

    Python 带有一个大型的标准库。使用 import 访问库模块。示例:

    import math x = math.sqrt(10) import urllib.request u = urllib.request.urlopen('http://www.python.org/') data = u.read() 

    稍后,我们将更详细地介绍库和模块。

    错误和异常

    函数将错误报告为异常。异常会导致函数中止,如果未处理,可能会导致整个程序终止。

    在你的 Python 解释器( REPL )中尝试一下:

    >>> int('N/A') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: 'N/A' >>> 

    出于调试的目的,上面的错误信息描述了发生的情况,错误产生的位置以及回溯。该回溯显示导致失败的其它函数调用。

    捕获和处理异常

    异常可以被捕获并处理。要捕获异常,使用 try - except 语句:

    for line in f: fields = line.split() try: shares = int(fields[1]) except ValueError: print("Couldn't parse", line) ... 

    该名称 ValueError 必须与你尝试捕获的错误类型匹配。

    通常,根据所执行的操作,很难提前确切地知道可能会发生哪种错误。不管是好是坏,通常会添加在程序意外奔溃后的异常处理(示例:”天哪,我们忘记捕获错误了。我们应该处理错误的。“)。

    触发异常

    要触发异常,请使用 raise 语句:

    raise RuntimeError('What a kerfuffle') 

    这将导致程序因异常回溯而中止,除非该异常通过 try-except 代码块捕获。

    % python3 foo.py Traceback (most recent call last): File "foo.py", line 21, in <module> raise RuntimeError("What a kerfuffle") RuntimeError: What a kerfuffle 

    练习

    练习 1.29:定义一个函数

    尝试定义一个简单的函数:

    >>> def greeting(name): 'Issues a greeting' print('Hello', name) >>> greeting('Guido') Hello Guido >>> greeting('Paula') Hello Paula >>> 

    如果函数的第一条语句是字符串,那么它被当做文档字符串。尝试输入一个命令来显示该文档字符串,例如 help(greeting)

    练习 1.30:将脚本转换为函数

    把你在 练习 1.27pcost.py 程序编写的代码放到 portfolio_cost(filename) 函数里面。此函数以文件名作为输入,读取文件中的投资组合数据,把投资组合总的费用作为浮点数返回。

    要使用你的函数,请修改程序,使其看起来像下面这样:

    def portfolio_cost(filename): ... # Your code here ... cost = portfolio_cost('Data/portfolio.csv') print('Total cost:', cost) 

    运行程序时,你应该会看到和以前一样的输出。运行程序后,你也可以输入一下命令来交互式地调用函数:

    bash $ python3 -i pcost.py 

    这将允许你从交互模式调用函数:

    >>> portfolio_cost('Data/portfolio.csv') 44671.15 >>> 

    能够交互地试验代码对调试和测试非常有用。

    练习 1.31:错误处理

    如果你在缺少某些字段的文件上使用函数,会发生什么情况?

    >>> portfolio_cost('Data/missing.csv') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "pcost.py", line 11, in portfolio_cost nshares = int(fields[1]) ValueError: invalid literal for int() with base 10: '' >>> 

    在这一点上,你面临一个决定:要使程序正常工作,你可以通过消除错误行( bad lines )来清理原始输入文件,或者修改代码,以某种方式处理错误行。

    请修改 pcost.py 程序以捕获异常,打印警告信息然后继续处理文件余下部分。

    练习 1.32:使用库函数

    Python 带有一个拥有大量有用函数的大型标准库。csv 模块是一个在这里可能有用的库。无论何时,每当必须必须使用 CSV 数据文件时,都应使用 csv 模块。下面是一个有关 csv 模块是如何工作的示例:

    >>> import csv >>> f = open('Data/portfolio.csv') >>> rows = csv.reader(f) >>> headers = next(rows) >>> headers ['name', 'shares', 'price'] >>> for row in rows: 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 模块有一个非常棒的功能它处理各种底层细节,例如引号和适当的逗号拆分。在上面的输出中,你会注意到它从第一列的名称( names )中删除了双引号。

    修改你的 pcost.py 程序,以使用 csv 模块进行解析,然后尝试运行前面的示例。

    练习 1.33:从命令行读取

    pcost.py 程序中,输入文件的名称已经被硬编码到代码中:

    # pcost.py def portfolio_cost(filename): ... # Your code here ... cost = portfolio_cost('Data/portfolio.csv') print('Total cost:', cost) 

    虽然用于学习和测试还行,但在实际的程序中,你可能不会这么做。

    相反,你可以把文件名作为参数传递给脚本。尝试按以下步骤修改程序的底部:

    # pcost.py import sys def portfolio_cost(filename): ... # Your code here ... if len(sys.argv) == 2: filename = sys.argv[1] else: filename = 'Data/portfolio.csv' cost = portfolio_cost(filename) print('Total cost:', cost) 

    sys.argv 是一个列表,该列表包含了在命令行上传递的参数(如果有)。

    要运行程序,你需要从终端( terminal )运行 Python 。

    示例,从 Unix 系统中的 bash 运行:

    bash % python3 pcost.py Data/portfolio.csv Total cost: 44671.15 bash % 

    注:完整翻译见 https://github.com/codists/practical-python-zh

    2 条回复    2021-02-20 22:15:29 +08:00
    CoreJa
        1
    CoreJa  
       2021-02-19 14:47:34 +08:00
    好家伙,年前看到大佬你在翻译的时候还是第二章末尾,现在第四章都快搞完了,强的呀。

    我之前翻过一小部分 DRF 框架的文档,毕竟翻译其实更像是学习的时候顺手就翻了,要是可以的话我也想做点贡献,能否分享一下你的翻译计划?我可以提 pr 或者直接 push
    codists
        2
    codists  
    OP
       2021-02-20 22:15:29 +08:00
    @CoreJa
    哎呀妈呀,感动。看了大佬的博客,感觉比我厉害哈,这种小项目就不劳烦大佬了,待我搞一个大点的项目再请你指导指导。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1221 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 23:49 PVG 07:49 LAX 16:49 JFK 19:49
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86