4. More Control Flow Tools(深入控制流)


Besides the while statement just introduced, Python knows the usual control flow statements known from other languages, with some twists.

除了上一节介绍的 while 循环语句外,Python像其他语言一样支持常用的流程控制语句,当然也有一些自己的元素。

4.1. if Statements(if语句)

Perhaps the most well-known statement type is the if statement. For example:

if 语句也许是最有名的语句类型。例如:

>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...      x = 0
...      print('Negative changed to zero')
... elif x == 0:
...      print('Zero')
... elif x == 1:
...      print('Single')
... else:
...      print('More')
...
More

There can be zero or more elif parts, and the else part is optional. The keyword ‘elif‘ is short for ‘else if’, and is useful to avoid excessive indentation. An if ... elif ... elif ... sequence is a substitute for the switch or case statements found in other languages.

if 语句可以有零个或多个 elif 分支语句,并且 else 分支语句是可选的。 elif 关键字是’else if’的缩写,这可以有效避免过度缩进问题。在Python中,使用 if ... elif ... elif 语句组合代替像其他语言中的 switch 和 case 语句。

4.2. for Statements(for语句)

The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence. For example (no pun intended):

for语句可能与你在C或Pascal语言中用过的有些不同。与总是依靠一个等差数字进行迭代(类似Pascal)或者赋予用户定义迭代步进和终止条件的能力(类似C)不同,Python的 for 语句是对任何序列(列表或字符串)的项按照它们在序列中的顺序进行迭代。例如:

>>> # Measure some strings:
... a = ['cat', 'window', 'defenestrate']
>>> for x in a:
...     print(x, len(x))
...
cat 3
window 6
defenestrate 12

It is not safe to modify the sequence being iterated over in the loop (this can only happen for mutable sequence types, such as lists). If you need to modify the list you are iterating over (for example, to duplicate selected items) you must iterate over a copy. The slice notation makes this particularly convenient:

在循环中修改正在被迭代的序列是不安全的(这仅在可变序列类型上发生,像列表)。如果需要修改正在迭代的列表(比如复制选择的项),你必须对它的副本进行迭代。切片操作可以方便的做到这一点。

>>> for x in a[:]: # make a slice copy of the entire list
...    if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']

4.3. The range() Function(range()函数)

If you do need to iterate over a sequence of numbers, the built-in function range() comes in handy. It generates arithmetic progressions:

如果你必须迭代一个数字序列,内置函数 range() 会派上用场。它生成一个等差级数序列

>>> for i in range(5):
...     print(i)
...
0
1
2
3
4

The given end point is never part of the generated sequence; range(10) generates 10 values, the legal indices for items of a sequence of length 10. It is possible to let the range start at another number, or to specify a different increment (even negative; sometimes this is called the ‘step’):

给定的终值从不会包含在生成的列表中, range(10) 生成10个值,这些值可以作为一个长度为10的序列的合法索引。可以让 range 函数从另一个数值开始,或者指定一个不同的增量(甚至是负数,有时它被称为“步长”)。

range(5, 10)
   5 through 9

range(0, 10, 3)
   0, 3, 6, 9

range(-10, -100, -30)
  -10, -40, -70

To iterate over the indices of a sequence, you can combine range() and len() as follows:

为了迭代序列的索引,你可以结合使用 range() 和 len() (实现)。如下所示:

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb

In most such cases, however, it is convenient to use the enumerate() function, see Looping Techniques.

然而在大多数此类情况下,使用 enumerate() 函数更方便。参考 Looping Techniques 遍历技巧 。

A strange thing happens if you just print a range:

如果你只是打印一个 range (方法调用)会发生奇怪的事情。

>>> print(range(10))
range(0, 10)

In many ways the object returned by range() behaves as if it is a list, but in fact it isn’t. It is an object which returns the successive items of the desired sequence when you iterate over it, but it doesn’t really make the list, thus saving space.

在很多方面 range() 函数返回的对象表现为它是一个列表,但事实上它并不是。当你迭代它时,它是一个能够像期望的序列返回连续项的对象;但为了节省空间,它并不真正构造列表。

We say such an object is iterable, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. We have seen that the for statement is such an iterator. The function list() is another; it creates lists from iterables:我们称此类对象是

可迭代的 ,即适合作为那些期望从某些东西中获得连续项直到结束的函数或结构的一个目标(参数)。我们已经见过的 for 语句就是这样一个

迭代器。 list() 函数是另外一个(迭代器),它从可迭代(对象)中创建列表。

>>> list(range(5))
[0, 1, 2, 3, 4]

Later we will see more functions that return iterables and take iterables as argument.

稍后我们会看到更多返回可迭代(对象)和以可迭代(对象)作为参数的函数

4.4. break and continue Statements, and else Clauses on Loops(循环中的break,continue语句,else子句)

The break statement, like in C, breaks out of the smallest enclosing for or while loop.

像在C语言中一样, break 语句用于跳出最近的 for 循环或 while 循环。

The continue statement, also borrowed from C, continues with the next iteration of the loop.

continue 语句,同样借鉴自C语言,继续循环的下一次迭代过程。

Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement. This is exemplified by the following loop, which searches for prime numbers:

循环语句可以包含一个 else 子句,当循环因穷尽列表项( for 循环)或循环条件变为false( while 循环)而终止时执行它,而通过 break 语句结束循环时并不执行。下面这个搜索素数的循环是一个间的示例:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

(Yes, this is the correct code. Look closely: the else clause belongs to the for loop, not the if statement.)

这是正确的代码。仔细看,else子句附属于for循环而不是if语句

4.5. pass Statements(pass语句)

The pass statement does nothing. It can be used when a statement is required syntactically but the program requires no action. For example:

pass 语句不做任何事。它被用于语法结构上需要一条语句但并不做任何事时。例如:

>>> while True:
...     pass  # Busy-wait for keyboard interrupt (Ctrl+C)
...

This is commonly used for creating minimal classes:

这通常被用在创建最小类上。

>>> class MyEmptyClass:
...     pass
...

Another place pass can be used is as a place-holder for a function or conditional body when you are working on new code, allowing you to keep thinking at a more abstract level. The pass is silently ignored:

另外一个可以用 pass 的地方是当你新编写一个函数结构或条件体代码时,这使你在更抽象的层面思考。 pass 被默默的忽略。

>>> def initlog(*args):
...     pass   # Remember to implement this!
...

4.6. Defining Functions(函数定义)

We can create a function that writes the Fibonacci series to an arbitrary boundary:

我们可以创建一个输出指定边界的斐波那契数列的函数

>>> def fib(n):    # write Fibonacci series up to n
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print(a, end=' ')
...         a, b = b, a+b
...     print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

The keyword def introduces a function definition. It must be followed by the function name and the parenthesized list of formal parameters. The statements that form the body of the function start at the next line, and must be indented.

关键字 def 声明一个函数 定义 。其后必须跟着函数名和以括号标明的参数列表。必须在下一行开始构成函数体的语句,并且必须缩进。

The first statement of the function body can optionally be a string literal; this string literal is the function’s documentation string, or docstring. (More about docstrings can be found in the section Documentation Strings.) There are tools which use docstrings to automatically produce online or printed documentation, or to let the user interactively browse through code; it’s good practice to include docstrings in code that you write, so make a habit of it.

函数体的第一行语句可以是可选的字符串常量,这个字符串是函数的文档字符串,或者称为 docstring 。(更多关于 docstrings 的信息请参考 Documentation Strings 文档字符串 。)有些工具通过 docstrings 自动生成在线的或可打印的文档,或者让用户通过代码交互浏览;在你的代码中包含 docstrings 是一个好的实践,让它成为习惯吧。

The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names. Thus, global variables cannot be directly assigned a value within a function (unless named in a global statement), although they may be referenced.

函数调用会为函数局部变量生成一个新的符号表。确切的说,所有函数中的变量赋值都是将值存储在局部符号表。变量引用首先在局部符号表中查找,然后是包含函数的局部符号表,然后是全局符号表,最后是内置名字表。因此,全局变量不能在函数中直接赋值(除非用 global 语句命名),尽管他们可以被引用。

The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object). [1] When a function calls another function, a new local symbol table is created for that call.

当函数调用时,实参被引入调用函数的局部符号表;因此,参数是通过 传值 方式传递的(这里 值 总是指代对象的 引用 ,而非对象的值)。 [1] 当一个函数调用其他函数时,将为此调用创建一个新的字符表。

A function definition introduces the function name in the current symbol table. The value of the function name has a type that is recognized by the interpreter as a user-defined function. This value can be assigned to another name which can then also be used as a function. This serves as a general renaming mechanism:

一个函数定义会在当前符号表内引入函数名。函数名指代的值(即函数体)有一个被Python解释器认定为 用户自定义函数 的类型。这个值可以赋予其他的名字(即变量名),然后它也可以被当做函数使用。这可以作为通用的重命名机制:

>>> fib

  
  
   
   
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89

Coming from other languages, you might object that fib is not a function but a procedure since it doesn’t return a value. In fact, even functions without a return statement do return a value, albeit a rather boring one. This value is called None (it’s a built-in name). Writing the value None is normally suppressed by the interpreter if it would be the only value written. You can see it if you really want to using print():

如果你使用过其他语言,你可能会反对说: fib 不是一个函数,而是一个procedure(过程),因为它并不返回任何值。事实上,没有 return 语句的函数确实会返回一个值,虽然是一个相当令人厌烦的值(指 None )。这个值被称为 None (这是一个内建名称)。如果 None 值是唯一被书写的值,那么在写的时候通常会被解释器忽略(即不输出任何内容)。如果你确实想看到这个值的输出内容,请使用 print() 函数。

>>> fib(0)
>>> print(fib(0))
None

It is simple to write a function that returns a list of the numbers of the Fibonacci series, instead of printing it:

定义一个返回斐波那契数列数字列表的函数,而不是打印它,是很简单的:

>>> def fib2(n): # return Fibonacci series up to n
...     """Return a list containing the Fibonacci series up to n."""
...     result = []
...     a, b = 0, 1
...     while a < n:
...         result.append(a)    # see below
...         a, b = b, a+b
...     return result
...
>>> f100 = fib2(100)    # call it
>>> f100                # write the result
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

This example, as usual, demonstrates some new Python features:

照例,这个列子包含了一些Python的新特性:

The return statement returns with a value from a function. return without an expression argument returns None. Falling off the end of a function also returns None.

return 语句从函数中返回一个值(可以是多个)。没有表达式参数的 return 语句返回 None 值。函数执行最后(指没有 return 语句的情况)也会返回 None 值。

The statement result.append(a) calls a method of the list object result. A method is a function that ‘belongs’ to an object and is named obj.methodname, where obj is some object (this may be an expression), and methodname is the name of a method that is defined by the object’s type. Different types define different methods. Methods of different types may have the same name without causing ambiguity. (It is possible to define your own object types and methods, using classes, see Classes) The method append() shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to result = result + [a], but more efficient.

result.append(b) 语句调用了列表对象 result 的一个 方法 。方法是属于对象的函数,并被命名为 obj.methodname ,此处 obj 是某个对象(也可能是个表达式), methodname 是对象类型定义的方法的名字。不同的(对象)类型定义了不同的方法。不同(对象)类型的方法可能拥有相同的名字,但这并不会导致胡乱。(你可以使用 clasees 对应自己的对象类型和方法,参考 Classes 类 )示例中出现的 append() 方法是由列表对象定义的,它将一个新元素添加到列表的末尾。在这个示例中它等同于 result = result + [b] (表达式运算),但是更高效。

4.7. More on Defining Functions(深入函数定义)

It is also possible to define functions with a variable number of arguments. There are three forms, which can be combined.

在Python中,你也可以定义包含若干参数的函数。这里有三种可用的形式,也可以混合使用

4.7.1. Default Argument Values(默认参数值)

The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer arguments than it is defined to allow. For example:

最常用的一种形式是为一个或多个参数指定默认值。这会创建一个可以使用比定义时允许的参数更少的参数调用的函数:

def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
    while True:
        ok = input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        retries = retries - 1
        if retries < 0:
            raise IOError('refusenik user')
        print(complaint)

This function can be called in several ways:

这个函数可以通过几种方式调用:

  • giving only the mandatory argument: ask_ok('Do you really want to quit?')
  • 仅给出必须得参数:ask_ok('Do you really want to quit?')
  • giving one of the optional arguments: ask_ok('OK to overwrite the file?', 2)
  • 给出一个可选的参数:ask_ok('OK to overwrite the file?', 2)
  • or even giving all arguments: ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')
  • 或者给出所有的参数:ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')

This example also introduces the in keyword. This tests whether or not a sequence contains a certain value.

本示例同样介绍了 in 关键字。它检测序列中是否包含某个指定的值。

The default values are evaluated at the point of function definition in the defining scope, so that

默认值在定义范围内函数定义时求值,例如:

i = 5

def f(arg=i):
    print(arg)

i = 6
f()

will print 5.

将会打印5

Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:

强烈警告: 默认值只被求值一次。这使得当默认值是可变对象时会有所不同,比如列表、字典或者大多数类的实例。例如,下面的函数在后续调用过程中会累积(前面)传给它的参数。

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

This will print

它将会打印


[1] [1, 2] [1, 2, 3]


If you don’t want the default to be shared between subsequent calls, you can write the function like this instead:

如果你不想让默认值在后续调用中累积,你可以像下面一样定义函数。

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L
4.7.2. Keyword Arguments(关键字参数)

Functions can also be called using keyword arguments of the form keyword = value. For instance, the following function:

函数同样可以使用 keyword = value 形式的键字参数来调用。例如,下面的函数:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print("-- This parrot wouldn't", action, end=' ')
    print("if you put", voltage, "volts through it.")
    print("-- Lovely plumage, the", type)
    print("-- It's", state, "!")

could be called in any of the following ways:

可以使用如下任何方式来调用上面函数:


parrot(1000) parrot(action = 'VOOOOOM', voltage = 1000000) parrot('a thousand', state = 'pushing up the daisies') parrot('a million', 'bereft of life', 'jump')


but the following calls would all be invalid:

但是下面的一些调用将是无效的:


parrot() # required argument missing(缺少必要的参数) parrot(voltage=5.0, 'dead') # non-keyword argument following keyword(在关键字后存在非关键字参数) parrot(110, voltage=220) # duplicate value for argument(对同一参数多重赋值) parrot(actor='John Cleese') # unknown keyword(未知的关键字参数)


In general, an argument list must have any positional arguments followed by any keyword arguments, where the keywords must be chosen from the formal parameter names. It’s not important whether a formal parameter has a default value or not. No argument may receive a value more than once — formal parameter names corresponding to positional arguments cannot be used as keywords in the same calls. Here’s an example that fails due to this restriction:

通常,参数列表必须(先书写)位置参数然后才是关键字参数,这里关键字必须来自于形参名字。形参是否有一个默认值并不重要。任何参数都不能被多次赋值——在同一个调用中,与位置参数相同的形参名字不能用作关键字。这里有一个违反此限制而出错的例子:

>>> def function(a):
...     pass
...
>>> function(0, a=0)
Traceback (most recent call last):
  File "
  
  
   
   ", line 1, in ?
TypeError: function() got multiple values for keyword argument 'a'

When a final formal parameter of the form **name is present, it receives a dictionary (see Mapping Types — dict) containing all keyword arguments except for those corresponding to a formal parameter. This may be combined with a formal parameter of the form *name (described in the next subsection) which receives a tuple containing the positional arguments beyond the formal parameter list. (*name must occur before **name.) For example, if we define a function like this:

当最后一个形参为 **name 形式时,函数接受一个包含所有未出现在形参列表中的关键字参数的字典(参考 Mapping Types — dict )。这可以结合形式为 *name 的形参(在下一节中介绍)一起使用,它接受一个包含所有未出现在形参列表中的位置参数的元组( *name 必须出现在 **name 之前)。例如,我们定义如下函数:

def cheeseshop(kind, *arguments, **keywords):
    print("-- Do you have any", kind, "?")
    print("-- I'm sorry, we're all out of", kind)
    for arg in arguments:
        print(arg)
    print("-" * 40)
    keys = sorted(keywords.keys())
    for kw in keys:
        print(kw, ":", keywords[kw])

It could be called like this:

它可能被这样调用:

cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin",
           client="John Cleese",
           sketch="Cheese Shop Sketch")

and of course it would print:

它将输出:


-- Do you have any Limburger ? -- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very, VERY runny, sir. ---------------------------------------- client : John Cleese shopkeeper : Michael Palin sketch : Cheese Shop Sketch


Note that the list of keyword argument names is created by sorting the result of the keywords dictionary’s keys() method before printing its contents; if this is not done, the order in which the arguments are printed is undefined.

注意:关键字参数名的列表内容在打印前需要对关键字字典的 keys() 方法返回的值排序(即在输出列表前需要对列表的键排序),否则参数输出的循序是未知的。

4.7.3. Arbitrary Argument Lists(可变参数列表)

Finally, the least frequently used option is to specify that a function can be called with an arbitrary number of arguments. These arguments will be wrapped up in a tuple (see Tuples and Sequences). Before the variable number of arguments, zero or more normal arguments may occur.

最后,指明一个函数可以使用任意数目的参数调用是极少的选择。这些参数将被包装进一个元组(参考 Tuples and Sequences 元组和序列 )。在可变数目的参数前,可以有零或多个普通的参数。

def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))

Normally, these variadic arguments will be last in the list of formal parameters, because they scoop up all remaining input arguments that are passed to the function. Any formal parameters which occur after the *args parameter are ‘keyword-only’ arguments, meaning that they can only be used as keywords rather than positional arguments.

通常,这些 可变化的 参数在形参列表的最后定义,因为他们会收集传递给函数的所有剩下的输入参数。任何出现在 *args 参数之后的形参只能是“关键字参数”,即他们只能通过关键字而非位置参数使用。

>>> def concat(*args, sep="/"):
...    return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'
4.7.4. Unpacking Argument Lists(拆分参数列表)

The reverse situation occurs when the arguments are already in a list or tuple but need to be unpacked for a function call requiring separate positional arguments. For instance, the built-in range() function expects separate start and stop arguments. If they are not available separately, write the function call with the *-operator to unpack the arguments out of a list or tuple:

一种相反的情况是:当参数是一个列表或元组但函数需要分开的位置参数时,就需要拆分参数。比如,内建函数 range() 期望独立的 start 和 stop 参数。如果他们不是独立的有效(参数),调用函数时使用 *- 操作符将参数从列表或元组中拆分出来即可。

>>> list(range(3, 6))            # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))            # call with arguments unpacked from a list
[3, 4, 5]

In the same fashion, dictionaries can deliver keyword arguments with the **-operator:

以此类推,字典可以使用 **- 操作符拆分成关键字参数。

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print("-- This parrot wouldn't", action, end=' ')
...     print("if you put", voltage, "volts through it.", end=' ')
...     print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
4.7.5. Lambda Forms(Lambda表达式)

By popular demand, a few features commonly found in functional programming languages like Lisp have been added to Python. With the lambda keyword, small anonymous functions can be created. Here’s a function that returns the sum of its two arguments: lambda a, b: a+b. Lambda forms can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just syntactic sugar for a normal function definition. Like nested function definitions, lambda forms can reference variables from the containing scope:

出于普遍需求,一些通常在函数式编程语言中出现的特性被加入到Python中,如Lisp。使用 lambda 关键字,可以创建短小的匿名函数。这里有一个返回两个参数之和的(Lambda)函数: lambda a, b: a+b 。 Lambda方式可是使用在任何需要函数对象的地方。出于语法的限制,他们只能是一个独立的表达式。从语义上讲,它们只是普通函数定义的语法糖。类似于嵌套函数定义,lambda方式可以从包含域内引用变量。

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
4.7.6. Documentation Strings(文档字符串)

Here are some conventions about the content and formatting of documentation strings.

这里是一些关于文档字符串内容和格式的约定。

The first line should always be a short, concise summary of the object’s purpose. For brevity, it should not explicitly state the object’s name or type, since these are available by other means (except if the name happens to be a verb describing a function’s operation). This line should begin with a capital letter and end with a period.

第一行应该总是关于对象用途的摘要。为了简便起见,无需明确说明对象的名称或类型,因为这些都可以通过其他方法获取(除非名字碰巧是描述一个函数操作的动词)。这一行应该以大写字母开头,并且以句号结束。

If there are more lines in the documentation string, the second line should be blank, visually separating the summary from the rest of the description. The following lines should be one or more paragraphs describing the object’s calling conventions, its side effects, etc.

如果文档字符串包含多行,第二行应该是空行,在视觉上将摘要(指第一行)与区域的描述内容分割。接下来应该是一段或多段(内容),用来描述对象调用约定和边界效应等。

The Python parser does not strip indentation from multi-line string literals in Python, so tools that process documentation have to strip indentation if desired. This is done using the following convention. The first non-blank line after the first line of the string determines the amount of indentation for the entire documentation string. (We can’t use the first line since it is generally adjacent to the string’s opening quotes so its indentation is not apparent in the string literal.) Whitespace “equivalent” to this indentation is then stripped from the start of all lines of the string. Lines that are indented less should not occur, but if they occur all their leading whitespace should be stripped. Equivalence of whitespace should be tested after expansion of tabs (to 8 spaces, normally).

在Python中,语法分析器不会从多行字符串中去除缩进,因此如果需要处理文档的工具必须自己去除缩进。这是通过以下的约定实现的:第一行 之后 的第一个非空行决定了整个文档字符串缩进的值。(我们不用第一行是因为它通常紧接在字符串起始引号,以致它在字符串中的缩进并不明显。)字符串中所有行开始的“相当于”缩进的空白都会被去除掉。不应出现缩进不足的行(指有的行缩进空格数少于整体),如果出现此情况所有的前导空白都应该被去除。在扩展制表符后需要对相等的空白做测试(通常为8个空格)。

Here is an example of a multi-line docstring:

这里是一个多行docstring的示例:

>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything.
...     """
...     pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.

    No, really, it doesn't do anything.

4.8. Intermezzo: Coding Style(编码风格)

Now that you are about to write longer, more complex pieces of Python, it is a good time to talk about coding style. Most languages can be written (or more concise, formatted) in different styles; some are more readable than others. Making it easy for others to read your code is always a good idea, and adopting a nice coding style helps tremendously for that.

现在你可以编写更长更复杂的python代码块,现在是该谈论代码风格了。许多语言可以使用多种风格编写(或者更简洁、格式化);有些比其它更具有可读性。将你的代码更容易阅读是一个好主意,采取良好的代码风格极大有助于这些.

For Python, PEP 8 has emerged as the style guide that most projects adhere to; it promotes a very readable and eye-pleasing coding style. Every Python developer should read it at some point; here are the most important points extracted for you:对于Python而言, PEP 8 已经成为大多数项目使用的风格,它提供了一个非常可读的并且诱人的编码风格。每一位Python开发者都应该找个时间读一下它,这里是为你概括的最重要的几点:

Use 4-space indentation, and no tabs.

使用4个空格的缩进,并杜绝制表符。

4 spaces are a good compromise between small indentation (allows greater nesting depth) and large indentation (easier to read). Tabs introduce confusion, and are best left out.

4个空格是一个介于小缩进(允许更深层的嵌套)和大缩进(更利于阅读)好的折中(选择)。制表符会导致混乱(因为不同编辑器上的制表符表示的空格可能不同),最好将它遗忘。

Wrap lines so that they don’t exceed 79 characters.

换行,避免他们超过79个字符。

This helps users with small displays and makes it possible to have several code files side-by-side on larger displays.

这可以帮助使用小显示器的用户,并且使得在大显示器上并排显示几个代码文件成为可能。

Use blank lines to separate functions and classes, and larger blocks of code inside functions.

使用空行分割类和函数以及函数内部较大的代码块。

When possible, put comments on a line of their own.

如果可以,将注释独立成行。

Use docstrings.

使用文档字符串

Use spaces around operators and after commas, but not directly inside bracketing constructs: a = f(1, 2) + g(3, 4).

在操作符两侧和逗号之后使用空格,但不要直接在括号内部使用: a = f(1, 2) + g(3, 4) 。

Name your classes and functions consistently; the convention is to use CamelCase for classes and lower_case_with_underscores for functions and methods. Always use self as the name for the first method argument (see A First Look at Classes for more on classes and methods).

使用统一风格命名你的类和函数:约定使用 CamelCase 方式命名类,使用 lower_case_with_underscores 方式命名函数和方法。总是用 self 作为方法的第一个参数名(参考 A First Look at Classes 初识类 深入类和方法)。

Don’t use fancy encodings if your code is meant to be used in international environments. Python’s default, UTF-8, or even plain ASCII work best in any case.

如果你希望你的代码被用在国际环境中,不要使用新奇的编码。 Python默认的UTF-8编码甚至ASCII编码在任何情况下都将工作的更好

Likewise, don’t use non-ASCII characters in identifiers if there is only the slightest chance people speaking a different language will read or maintain the code.

同样的,如果仅有极少数说其他语言的人将要阅读或维护代码,不要使用非ASCII字符的标识符

Footnotes(脚注)

[1] Actually, call by object reference would be a better description, since if a mutable object is passed, the caller will see any changes the callee makes to it (items inserted into a list).

事实上, 对象引用调用 可能是个更好的表述,因为如果传递一个可变对象(参数),调用者将会观察到被调用者对其所做的任何改变(向列表插入元素)。