|
| 1 | +# 1.4 实践指南:函数的艺术 |
| 2 | + |
| 3 | +> 来源:[1.4 Practical Guidance: The Art of the Function](http://www-inst.eecs.berkeley.edu/~cs61a/sp12/book/functions.html#practical-guidance-the-art-of-the-function) |
| 4 | +
|
| 5 | +> 译者:[飞龙](https://github.com/wizardforcel) |
| 6 | +
|
| 7 | +> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) |
| 8 | +
|
| 9 | +函数是所有程序的要素,无论规模大小,并且在编程语言中作为我们表达计算过程的主要媒介。目前为止,我们讨论了函数的形式特性,以及它们如何使用。我们现在跳转到如何编写良好的函数这一话题。 |
| 10 | + |
| 11 | ++ 每个函数都应该只做一个任务。这个任务可以使用短小的名称来定义,使用一行文本来标识。顺序执行多个任务的函数应该拆分在多个函数中。 |
| 12 | ++ 不要重复劳动(DRY)是软件工程的中心法则。所谓的DRY原则规定多个代码段不应该描述重复的逻辑。反之,逻辑应该只实现一次,指定一个名称,并且多次使用。如果你发现自己在复制粘贴一段代码,你可能发现了一个使用函数抽象的机会。 |
| 13 | ++ 函数应该定义得通常一些,准确来说,平方并不是在 Python 库中,因为它是`pow`函数的一个特例,这个函数计算任何数的任何次方。 |
| 14 | + |
| 15 | +这些准则提升代码的可读性,减少错误数量,并且通常使编写的代码总数最小。将复杂的任务拆分为简洁的函数是一个技巧,它需要一些经验来掌握。幸运的是,Python 提供了一些特性来支持你的努力。 |
| 16 | + |
| 17 | +## 1.4.1 文档字符串 |
| 18 | + |
| 19 | +函数定义通常包含描述这个函数的文档,叫做文档字符串,它必须在函数体中缩进。文档字符串通常使用三个引号。第一行描述函数的任务。随后的一些行描述参数,并且澄清函数的行为: |
| 20 | + |
| 21 | +```py |
| 22 | +>>> def pressure(v, t, n): |
| 23 | + """Compute the pressure in pascals of an ideal gas. |
| 24 | +
|
| 25 | + Applies the ideal gas law: http://en.wikipedia.org/wiki/Ideal_gas_law |
| 26 | +
|
| 27 | + v -- volume of gas, in cubic meters |
| 28 | + t -- absolute temperature in degrees kelvin |
| 29 | + n -- particles of gas |
| 30 | + """ |
| 31 | + k = 1.38e-23 # Boltzmann's constant |
| 32 | + return n * k * t / v |
| 33 | +``` |
| 34 | + |
| 35 | +当你以函数名称作为参数来调用`help`时,你会看到它的文档字符串(按下`q`来退出 Python 帮助)。 |
| 36 | + |
| 37 | +```py |
| 38 | +>>> help(pressure) |
| 39 | +``` |
| 40 | + |
| 41 | +编写 Python 程序时,除了最简单的函数之外,都要包含文档字符串。要记住,代码只编写一次,但是会阅读多次。Python 文档包含了[文档字符串准则](http://www.python.org/dev/peps/pep-0257/),它在不同的 Python 项目中保持一致。 |
| 42 | + |
| 43 | +## 1.4.2 参数默认值 |
| 44 | + |
| 45 | +定义普通函数的结果之一就是额外参数的引入。具有许多参数的函数调用起来非常麻烦,也难以阅读。 |
| 46 | + |
| 47 | +在 Python 中,我们可以为函数的参数提供默认值。调用这个函数时,带有默认值的参数是可选的。如果它们没有提供,默认值就会绑定到形式参数的名称上。例如,如果某个应用通常用来计算一摩尔粒子的压强,这个值就可以设为默认: |
| 48 | + |
| 49 | +```py |
| 50 | +>>> k_b=1.38e-23 # Boltzmann's constant |
| 51 | +>>> def pressure(v, t, n=6.022e23): |
| 52 | + """Compute the pressure in pascals of an ideal gas. |
| 53 | +
|
| 54 | + v -- volume of gas, in cubic meters |
| 55 | + t -- absolute temperature in degrees kelvin |
| 56 | + n -- particles of gas (default: one mole) |
| 57 | + """ |
| 58 | + return n * k_b * t / v |
| 59 | +>>> pressure(1, 273.15) |
| 60 | +2269.974834 |
| 61 | +``` |
| 62 | + |
| 63 | +这里,`pressure`的定义接受三个参数,但是在调用表达式中只提供了两个。这种情况下,`n`的值通过`def`语句的默认值获得(它看起来像对`n`的赋值,虽然就像这个讨论暗示的那样,更大程度上它是条件赋值)。 |
| 64 | + |
| 65 | +作为准则,用于函数体的大多数数据值应该表示为具名参数的默认值,这样便于查看,以及被函数调用者修改。一些值永远不会改变,就像基本常数`k_b`,应该定义在全局帧中。 |
0 commit comments