4.More Control Flow Tools 控制流工具

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語(yǔ)句知染, Python從其他語(yǔ)言中借鑒了常用的控制流語(yǔ)句双霍,并做了部分修改报破。

4.1. if Statements If 語(yǔ)句

Perhaps the most well-known statement type is the if statement. For example:
也許就著名的語(yǔ)句類型就是if語(yǔ)句了续语。例如:

>>> 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 ifelifelif … sequence is a substitute for the switchor case statements found in other languages.
這里可以有0個(gè)或多個(gè) elif, 并且 else語(yǔ)句也是可選的犬第。 關(guān)鍵字 elifelse if 的縮寫诀姚,這樣可以有效的避免過(guò)多的縮進(jìn)。 一個(gè)if ... elif ... elif ... 語(yǔ)句是其他語(yǔ)言中 switch 或 case 語(yǔ)句的替代品妓湘。

4.2. for Statements For 語(yǔ)句

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):
Python中的for語(yǔ)句和你在C或Pascal語(yǔ)言中使用的有點(diǎn)不一樣查蓉。 不像Pascal中一直是算數(shù)級(jí)數(shù)的迭代,或者C中允許用戶定義迭代的步長(zhǎng)和停止循環(huán)條件榜贴,Python中的for語(yǔ)句是在按元素序列(字符串或列表)中的順序迭代豌研。例如(沒(méi)有語(yǔ)義雙關(guān)):

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

If you need to modify the sequence you are iterating over while inside the loop (for example to duplicate selected items), it is recommended that you first make a copy. Iterating over a sequence does not implicitly make a copy. The slice notation makes this especially convenient:
如果你想要在循環(huán)迭代中修改列表(例如重復(fù)選中的元素),建議你首先做一個(gè)備份。序列中的迭代不會(huì)做隱性備份鹃共,切片法讓這個(gè)很簡(jiǎn)單:

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

With for w in words:, the example would attempt to create an infinite list, inserting defenestrate over and over again.
相對(duì)于 or w in words:, 這個(gè)例子將會(huì)創(chuàng)建一個(gè)無(wú)限的列表鬼佣,一直重復(fù)插入'defenestrate'。(譯者注:因?yàn)?code>insert操作的是word列表本身霜浴,如果一直循環(huán)迭代元素的也是word本身晶衷,就會(huì)陷入死循環(huán)。用了切片來(lái)復(fù)制一個(gè)word列表來(lái)循環(huán)迭代阴孟,這個(gè)時(shí)候新插入的元素就不會(huì)影響到迭代了晌纫。)

4.3. The range() Function range() 函數(shù)

If you do need to iterate over a sequence of numbers, the built-in function range() comes in handy. It generates arithmetic progressions:
如果你需要在數(shù)字序列中迭代,內(nèi)置的函數(shù)range()就可以順手拈來(lái)永丝。下面的例如可以產(chǎn)生一個(gè)算數(shù)級(jí)數(shù):

>>> 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’):
這個(gè)給定的結(jié)束點(diǎn)從來(lái)都不是產(chǎn)生序列的一部分锹漱。range() 產(chǎn)生10個(gè)值,一個(gè)長(zhǎng)度是10的序列中元素合法的下標(biāo)类溢×枋撸可以讓這個(gè)范圍起始于另外一個(gè)號(hào)碼,或者指定一個(gè)不同的增長(zhǎng)(甚至是負(fù)數(shù)增長(zhǎng)闯冷,有時(shí)也叫做步長(zhǎng)):

range(5, 10)
   5, 6, 7, 8, 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()來(lái)迭代遍歷序列的下標(biāo):

>>> 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() 函數(shù)是更方便的蛇耀,可以查看Looping Techniques:循環(huán)的技巧.

A strange thing happens if you just print a range:
當(dāng)你打印一個(gè)range時(shí),會(huì)發(fā)生奇怪的事情:

>>> 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() 返回的對(duì)象表現(xiàn)得它好像是一個(gè)列表纺涤,但實(shí)際上它不是。它是當(dāng)你迭代遍歷一個(gè)期望的序列中連續(xù)的元素時(shí)返回的一個(gè)對(duì)象抠忘,但并沒(méi)有真正的創(chuàng)建一個(gè)列表撩炊,從而節(jié)省空間。

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:
我們所說(shuō)的這個(gè)對(duì)象就是迭代器: 很適合作為那些期望獲得連續(xù)的元素直到最后的函數(shù)和構(gòu)造器的目標(biāo)崎脉。我們可以看出for語(yǔ)句就是這個(gè)迭代器拧咳,list()函數(shù)就是另外一個(gè),它從迭代器中創(chuàng)建列表:

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

Later we will see more functions that return iterables and take iterables as argument.
稍后我們將會(huì)看到更多函數(shù)返回迭代器并將迭代器作為參數(shù)囚灼。

4.4. break and continue Statements, and else Clauses on Loops

循環(huán)中的breakcontinue語(yǔ)句骆膝,以及 else條款

The break statement, like in C, breaks out of the innermost enclosing for or while loop.
break語(yǔ)句,跟C中的一樣灶体,跳出forwhile 最里面的一層循環(huán)阅签。

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:
循環(huán)語(yǔ)句中也可以有一個(gè)else分支。當(dāng)循環(huán)遍歷完列表后中斷或循環(huán)條件為假時(shí)就會(huì)執(zhí)行蝎抽,但不是當(dāng)循環(huán)是通過(guò)break終止的時(shí)候政钟。下面查找質(zhì)數(shù)的循環(huán)就是例證:

>>> 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循環(huán)的精算,不是if語(yǔ)句)

When used with a loop, the else clause has more in common with the else clause of a try statement than it does that of if statements: a try statement’s else clause runs when no exception occurs, and a loop’s elseclause runs when no break occurs. For more on the try statement and exceptions, see Handling Exceptions.
當(dāng)使用一個(gè)循環(huán)的時(shí)候,else條款跟 try語(yǔ)句的else有更多的共同點(diǎn)层坠,而不是 if中的殖妇。當(dāng)沒(méi)有異常發(fā)生的時(shí)候,try語(yǔ)句中的else條款運(yùn)行破花,當(dāng)沒(méi)有break發(fā)生的時(shí)候谦趣,循環(huán)中的else條款執(zhí)行。更多關(guān)于try語(yǔ)句和異常座每,請(qǐng)查看 Handling Exceptions:處理異常.

The continue statement, also borrowed from C, continues with the next iteration of the loop:
continue語(yǔ)句前鹅,也是借鑒了C中的,在循環(huán)中繼續(xù)下一次迭代:

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9

4.5. pass Statements Pass 語(yǔ)句

The pass statement does nothing. It can be used when a statement is required syntactically but the program requires no action. For example:
pass 語(yǔ)句不做任何事峭梳。當(dāng)僅僅是一個(gè)語(yǔ)句的語(yǔ)法要求但程序并沒(méi)有任何操作要求時(shí)舰绘,可以使用它.例如:

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

This is commonly used for creating minimal classes:
這個(gè)也經(jīng)常用來(lái)創(chuàng)建一個(gè)最小的類:

>>> 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:
另外一個(gè)用到pass的地方就是當(dāng)你在寫新的代碼的時(shí)候,可以用它為函數(shù)或條件體占位葱椭,這樣允許你在一個(gè)更加抽象的水平來(lái)繼續(xù)你的思考捂寿。pass就會(huì)被默默的忽略:

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

4.6. Defining Functions 定義函數(shù)

We can create a function that writes the Fibonacci series to an arbitrary boundary:
我們可以創(chuàng)建一個(gè)函數(shù)來(lái)寫出隨意邊界的斐波那契數(shù)列:

>>> 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.
關(guān)鍵字def介紹了一個(gè)函數(shù)的定義。它后面必須跟著函數(shù)名和括號(hào)內(nèi)的形參數(shù)列表孵运。組成函數(shù)體的語(yǔ)句在下一行開(kāi)始秦陋,并且必須縮進(jìn)。

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.
函數(shù)體的第一個(gè)語(yǔ)句可以選擇是一個(gè)字符串常量治笨。這個(gè)字符串常量是這個(gè)函數(shù)的文檔字符串(更多關(guān)于文檔字符串可以在[Documentation Strings 文檔字符串]節(jié)選查看(https://docs.python.org/3/tutorial/controlflow.html#tut-docstrings))驳概。這些是用文檔字符串來(lái)自動(dòng)生成線上或打印文檔,或讓用戶通過(guò)瀏覽代碼來(lái)進(jìn)行交互的工具旷赖。寫代碼的時(shí)候包含文檔字符串是一個(gè)很好的實(shí)踐顺又,所以請(qǐng)把這個(gè)作為一個(gè)習(xí)慣來(lái)看待。

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.
函數(shù)的執(zhí)行引入了用戶幻術(shù)局部變量的新字符表等孵。更準(zhǔn)確的說(shuō)稚照,函數(shù)中的所有變量
賦值都存儲(chǔ)在本地符號(hào)表中。而變量引用首先在本地符號(hào)表查找流济,然后是在關(guān)閉本函數(shù)的本地符號(hào)表去查找锐锣,然后是在全局符號(hào)表,最后是在內(nèi)置名稱表中查找绳瘟。因此雕憔,盡管可以引用全局變量,但是不能直接在函數(shù)賦值(除非在全局變量中命名)糖声。

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.
當(dāng)一個(gè)函數(shù)被調(diào)用的時(shí)候斤彼,函數(shù)調(diào)用的實(shí)參會(huì)被引入被調(diào)用函數(shù)的本地符號(hào)表分瘦。因此,參數(shù)會(huì)通過(guò)值調(diào)用來(lái)傳遞的(這個(gè)值始終是一個(gè)對(duì)象的引用琉苇,而不是對(duì)象的值)嘲玫。當(dāng)一個(gè)函數(shù)調(diào)用另外一個(gè)函數(shù),一個(gè)新的本地符號(hào)表將會(huì)為這個(gè)調(diào)用而創(chuàng)建并扇。

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:
函數(shù)定義在當(dāng)前符號(hào)表中引入了函數(shù)名去团。函數(shù)名的值具讓解釋器將其識(shí)別為用戶定義函數(shù)的類型。

>>> fib
<function fib at 10042ed0>
>>> 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():
從其他語(yǔ)言來(lái)看穷蛹,你可能認(rèn)為fib不是一個(gè)函數(shù)土陪,而是一個(gè)過(guò)程,因?yàn)樗鼪](méi)有返回值肴熏。事實(shí)上鬼雀,即使函數(shù)沒(méi)有return語(yǔ)句,也始終會(huì)返回一個(gè)值蛙吏,即使是個(gè)沒(méi)有很無(wú)聊的值源哩。這個(gè)值被稱為 None(這是一個(gè)內(nèi)置的名稱)。如果None是唯一被打印的值鸦做,解釋器通常是抑制打印輸出的(譯者注:也就是省略打印None)励烦。如果你真的想要看看你可以使用print():

>>> fib(0)   #這個(gè)按回車之后解釋器沒(méi)有任何輸出
>>> print(fib(0))   #實(shí)際這個(gè)函數(shù)的返回值是一個(gè)None
None

It is simple to write a function that returns a list of the numbers of the Fibonacci series, instead of printing it:
很容易寫一個(gè)函數(shù)來(lái)返回斐波那契數(shù)列列表的函數(shù),來(lái)替代直接打印輸出:

>>> 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:
這個(gè)例子泼诱,跟往常一樣崩侠,演示了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 語(yǔ)句從函數(shù)中返回一個(gè)值。return語(yǔ)句中沒(méi)有任何表達(dá)式參數(shù)將會(huì)返回None坷檩。在函數(shù)的最后前運(yùn)行出錯(cuò)也會(huì)返回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(a) 語(yǔ)句調(diào)用了列表對(duì)象 result的方法改抡。一個(gè)方法就是一個(gè)屬于一個(gè)對(duì)象的函數(shù)矢炼,命名為 obj.methodname,這個(gè)obj就是對(duì)象(這里也可以是一個(gè)表達(dá)式)阿纤,methodname就是這個(gè)對(duì)象類型定義的方法名句灌。不同的類型定義不同的方法。不同的方法可以有同樣的命名且不引起歧義欠拾。(你可以用類來(lái)定義你自己的對(duì)象類型和方法胰锌,具體查看Classes) 這個(gè)例子中展示的方法append()就是列表對(duì)象定義的。它在列表的末尾添加一個(gè)新的元素藐窄。在這個(gè)例子中资昧,它等價(jià)于 result = result + [a], 當(dāng)更高效。

4.7. More on Defining Functions 更多關(guān)于定義函數(shù)

It is also possible to define functions with a variable number of arguments. There are three forms, which can be combined.
也可以定義一個(gè)參數(shù)數(shù)量可變的函數(shù)荆忍。這里有三種形式格带,可以組合使用:

4.7.1. Default Argument Values 默認(rèn)參數(shù)值

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:
最有用的形式就是指定一個(gè)或多個(gè)參數(shù)的默認(rèn)值撤缴。這樣創(chuàng)建的函數(shù)運(yùn)行在被調(diào)用的時(shí)候的參數(shù)比定義要求的個(gè)數(shù)更少。例如:

def ask_ok(prompt, retries=4, reminder='Please try again!'):
    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 ValueError('invalid user response')
        print(reminder)

This function can be called in several ways:

  • giving only the mandatory argument: ask_ok('Do you really want to quit?')
  • giving one of the optional arguments: ask_ok('OK to overwrite the file?', 2)
  • or even giving all arguments: ask_ok('OK to overwrite the file?', 2, 'Come on, only yesor no!')

這個(gè)函數(shù)可以通過(guò)幾種方式調(diào)用:

  • 只提供必須的參數(shù):ask_ok('Do you really want to quit?')
  • 提供一個(gè)可選的參數(shù): ask_ok('Do you really want to quit?', 2)
  • 或者提供所有參數(shù):ask_ok('OK to overwrite the file?', 2, 'Come on, only yesor no!')

This example also introduces the in keyword. This tests whether or not a sequence contains a certain value.
這個(gè)例子也在in
關(guān)鍵字中介紹叽唱,這個(gè)用來(lái)測(cè)試一個(gè)序列中是否包含一個(gè)特定的值屈呕。

The default values are evaluated at the point of function definition in the defining scope, so that
這個(gè)默認(rèn)值在函數(shù)定義的范圍內(nèi)有效,所以

i = 5

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

i = 6
f()

will print 5.
將會(huì)打印 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:
重點(diǎn)提示: 默認(rèn)值只會(huì)被計(jì)算一次棺亭。當(dāng)這個(gè)默認(rèn)值是類似列表虎眨,字典或者大部分類的實(shí)例這些容易變化的對(duì)象時(shí),就會(huì)有點(diǎn)不同镶摘。例如嗽桩,下面的函數(shù)會(huì)在后面的調(diào)用中積累參數(shù)。

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

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

This will print
這個(gè)將會(huì)打印

[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:
如果你不行這個(gè)默認(rèn)值在隨后的調(diào)用中分享钉稍,你可以把函數(shù)寫成下面這個(gè)來(lái)代替:

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

4.7.2. Keyword Arguments 關(guān)鍵字參數(shù)

Functions can also be called using keyword arguments of the form kwarg=value. For instance, the following function:
函數(shù)也可以用kwarg=value這樣形式的關(guān)鍵字參數(shù)來(lái)調(diào)用涤躲。例如,下面的函數(shù):

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, "!")

accepts one required argument (voltage) and three optional arguments (state, action, and type). This function can be called in any of the following ways:
接收一個(gè)必選的參數(shù)(voltage)和三個(gè)可選的參數(shù)(state, action, and type). 這個(gè)函數(shù)可以用下面的任一方式來(lái)調(diào)用:

parrot(1000)                                          # 1 positional argument
parrot(voltage=1000)                                  # 1 keyword argument
parrot(voltage=1000000, action='VOOOOOM')             # 2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000)             # 2 keyword arguments
parrot('a million', 'bereft of life', 'jump')         # 3 positional arguments
parrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword

but all the following calls would be invalid:
但是下面所有的調(diào)用將會(huì)是非法的:

parrot()                     # required argument missing
parrot(voltage=5.0, 'dead')  # non-keyword argument after a keyword argument
parrot(110, voltage=220)     # duplicate value for the same argument
parrot(actor='John Cleese')  # unknown keyword argument

In a function call, keyword arguments must follow positional arguments. All the keyword arguments passed must match one of the arguments accepted by the function (e.g. actor is not a valid argument for the parrotfunction), and their order is not important. This also includes non-optional arguments (e.g. parrot(voltage=1000) is valid too). No argument may receive a value more than once. Here’s an example that fails due to this restriction:
在函數(shù)調(diào)用中贡未,關(guān)鍵字參數(shù)必須遵循位置參數(shù)种樱。所有的關(guān)鍵字參數(shù)傳遞必須匹配函數(shù)接收的某個(gè)參數(shù)(例如 actorparrot函數(shù)中就是一個(gè)非法的參數(shù)),并且他們的順序是不重要的俊卤。這個(gè)也包括非可選參數(shù)(例如parrot(voltage=1000)也是合法的)嫩挤。沒(méi)有參數(shù)可以接收超過(guò)一次的值,這里有個(gè)例子就是因?yàn)檫@個(gè)限制而失敗的:

>>> def function(a):
...     pass
...
>>> function(0, a=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
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:
當(dāng)形參是以**name的形式出現(xiàn)時(shí)消恍,它接收一個(gè)字典(具體看 Mapping Types — dict Map類型--字典)岂昭,包含所有的除了與其他形參相關(guān)聯(lián)的關(guān)鍵字參數(shù)。這可以跟*name形式的形參結(jié)合起來(lái)(會(huì)在下一節(jié)討論),它接收包含形參列表之外的位置參數(shù)的元組狠怨。(*name必須出現(xiàn)在**name 之前)约啊。例如,如果我們定義一個(gè)這樣的函數(shù):

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)
    for kw in keywords:
        print(kw, ":", keywords[kw])

It could be called like this:
它可以這樣被調(diào)用:

 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:
當(dāng)然這樣就會(huì)打印:

-- 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.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch

Note that the order in which the keyword arguments are printed is guaranteed to match the order in which they were provided in the function call.
注意到打印的關(guān)鍵字參數(shù)的順序保證了它們?cè)诤瘮?shù)調(diào)用中的順序佣赖。

4.7.3. Arbitrary Argument Lists[] 隨意參數(shù)列表

(https://docs.python.org/3/tutorial/controlflow.html#arbitrary-argument-lists "Permalink to this headline")

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.
最后恰矩,最不常用的選項(xiàng)就是調(diào)用一個(gè)任意數(shù)量參數(shù)的函數(shù)。這些參數(shù)會(huì)被包含在一個(gè)元組(請(qǐng)看Tuples and Sequences 元組和序列)憎蛤。在可變數(shù)量的參數(shù)之前外傅,0個(gè)或者更多正常的參數(shù)都可能出現(xiàn)。

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 *argsparameter are ‘keyword-only’ arguments, meaning that they can only be used as keywords rather than positional arguments.
正常情況下俩檬,那些可變參數(shù)會(huì)在形參列表的最后萎胰,因?yàn)樗麄兂薪恿藗鹘o函數(shù)的剩下的輸入?yún)?shù)。出現(xiàn)在*args后面的任何形參都只能是關(guān)鍵子參數(shù)棚辽,這也意味著他們只能夠被用作關(guān)鍵字參數(shù)技竟,而不是位置參數(shù)。

>>> 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[] 參數(shù)列表的拆分 (https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists "Permalink to this headline")

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:
相反的是當(dāng)參數(shù)已經(jīng)是一個(gè)列表或元組晚胡,卻需要為要求獨(dú)立位置參數(shù)的函數(shù)調(diào)用把參數(shù)拆分開(kāi)灵奖。例如嚼沿, 內(nèi)置函數(shù)range() 期待分離的開(kāi)始和末尾參數(shù)。如果他們不能分別單獨(dú)獲取瓷患,可以用*操作符來(lái)寫函數(shù)調(diào)用骡尽,將參數(shù)從列表或元組中拆分出來(lái)。

>>> 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:
同樣的方法擅编,字典可以用**傳遞關(guān)鍵字參數(shù):

>>> 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 Expressions[] Lambda 表達(dá)式

(https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions "Permalink to this headline")

Small anonymous functions can be created with the lambda keyword. This function returns the sum of its two arguments: lambda a, b: a+b. Lambda functions 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 functions can reference variables from the containing scope:
小的匿名函數(shù)可以通過(guò)lambda 關(guān)鍵字創(chuàng)建攀细。函數(shù) lambda a, b: a+b 返回兩個(gè)參數(shù)的和。Lambda函數(shù)可以用在任何要求函數(shù)對(duì)象的地方爱态。由于語(yǔ)法限制谭贪,他們只能有一個(gè)單獨(dú)的表達(dá)式。語(yǔ)義上講锦担,它們只是普通函數(shù)定義中的一個(gè)語(yǔ)法技巧俭识。類似嵌套函數(shù)的定義,Lambda函數(shù)可以從包含范圍內(nèi)引用變量洞渔。

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

The above example uses a lambda expression to return a function. Another use is to pass a small function as an argument:
上面的例子用一個(gè)Lambda表達(dá)式來(lái)返回一個(gè)函數(shù)套媚。另一個(gè)用法是傳遞一個(gè)小函數(shù)作為參數(shù):

>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

4.7.6. Documentation Strings[] 文檔字符串(https://docs.python.org/3/tutorial/controlflow.html#documentation-strings "Permalink to this headline")

Here are some conventions about the content and formatting of documentation strings.
這里有一些關(guān)于文檔字符串的內(nèi)容和格式的規(guī)則。

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.
第一行應(yīng)該是關(guān)于對(duì)象用途的簡(jiǎn)介磁椒。簡(jiǎn)短起見(jiàn)堤瘤,不需要明確的陳述對(duì)象名或類型,因?yàn)檫@些可以從其他方面了解到浆熔。(除非這個(gè)名稱剛好就是描述函數(shù)操作的動(dòng)詞)這一行應(yīng)該以大寫字母開(kāi)頭本辐,以句號(hào)結(jié)尾。

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.
如果在文檔字符串中有多行医增,第二行應(yīng)該是空行慎皱,與下面的描述明確區(qū)分開(kāi)。接下來(lái)的文檔應(yīng)該有一個(gè)或多個(gè)段落來(lái)描述對(duì)象調(diào)用的約定和副作用等叶骨。

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解析器不會(huì)從多行的文檔字符串中去掉縮進(jìn)宝冕,所以如果需要的話,處理文檔的工具可以去掉多余的空行邓萨。這是使用下面的約定來(lái)完成的。文檔字符串中第一行后面的第一個(gè)非空行決定了整個(gè)文檔字符串的縮進(jìn)個(gè)數(shù)菊卷。(我們不能使用第一行缔恳,因?yàn)樗ǔJ青徑址鹗嫉囊?hào),所以它的縮進(jìn)在字符串文字中不明顯)空白相當(dāng)于脫離了所有行的字符串的開(kāi)始的縮進(jìn)洁闰∏干酰縮進(jìn)的行不應(yīng)該出現(xiàn),但是如果它們出現(xiàn)扑眉,則應(yīng)該剝離它們的所有前導(dǎo)空格纸泄。應(yīng)該測(cè)試tab鍵和空格鍵的等效性(正常一個(gè)tab等于8個(gè)空格)赖钞。

Here is an example of a multi-line docstring:
這里有個(gè)多行文檔字符串的例子:

>>> 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.7.7. Function Annotations[]

函數(shù)注解 (https://docs.python.org/3/tutorial/controlflow.html#function-annotations "Permalink to this headline")

Function annotations are completely optional metadata information about the types used by user-defined functions (see PEP 3107 and PEP 484 for more information).
函數(shù)注解是關(guān)于用戶自定義函數(shù)使用的類型的完全可選元數(shù)據(jù)信息。(詳細(xì)請(qǐng)查看 PEP 3107PEP 484

Annotations are stored in the __annotations__ attribute of the function as a dictionary and have no effect on any other part of the function. Parameter annotations are defined by a colon after the parameter name, followed by an expression evaluating to the value of the annotation. Return annotations are defined by a literal ->, followed by an expression, between the parameter list and the colon denoting the end of the def statement. The following example has a positional argument, a keyword argument, and the return value annotated:
注解以字典的形式保存在函數(shù)的__annotations__屬性中聘裁,對(duì)函數(shù)其他部分沒(méi)有影響雪营。參數(shù)注解是在參數(shù)名后的冒號(hào)定義,緊跟著一個(gè)表達(dá)式衡便,用來(lái)評(píng)估注解的值献起。返回值注解是由一個(gè)文本字符 -> 定義,后面跟隨一個(gè)表達(dá)式镣陕,處于參數(shù)列表和表示def語(yǔ)句結(jié)束的冒號(hào)之間.下面的例如有位置參數(shù)谴餐,關(guān)鍵字參數(shù)和返回值注解:

>>> def f(ham: str, eggs: str = 'eggs') -> str:
...     print("Annotations:", f.__annotations__)
...     print("Arguments:", ham, eggs)
...     return ham + ' and ' + eggs
...
>>> f('spam')
Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>}
Arguments: spam eggs
'spam and eggs'

4.8. Intermezzo: Coding Style[]

間奏曲:編碼風(fēng)格 (https://docs.python.org/3/tutorial/controlflow.html#intermezzo-coding-style "Permalink to this headline")

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.
現(xiàn)在你即將要寫更長(zhǎng)更復(fù)雜塊的Python代碼了,這是個(gè)談?wù)摼幋a風(fēng)格的好時(shí)機(jī)呆抑。大部分編程可以寫成不同風(fēng)格(或更簡(jiǎn)潔的說(shuō)岂嗓,格式化)。其中有一些相對(duì)而言更具有可讀性鹊碍。讓其他人更容易讀懂你的代碼總是極好的厌殉,而且采用好的編碼風(fēng)格對(duì)此有極大幫助。

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:
對(duì)于Python而言妹萨,PEP8 是作為大部分項(xiàng)目采用的風(fēng)格指導(dǎo)年枕。它推動(dòng)了非常具有可讀性且賞心悅目的編碼風(fēng)格。某種程度而言乎完,每一個(gè)Python開(kāi)發(fā)者都應(yīng)該讀一讀它熏兄。這里為你提取了最重要的幾點(diǎn):

  • Use 4-space indentation, and no tabs.
    使用4個(gè)空格的縮進(jìn),而不是tabs树姨。

    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 個(gè)空格是在小的縮進(jìn)(允許更大的嵌套深度)和大縮進(jìn)之間一個(gè)好的妥協(xié)摩桶。Tabs則會(huì)導(dǎo)致混亂,最好將其省略帽揪。

  • Wrap lines so that they don’t exceed 79 characters.
    換行硝清,所有它們不會(huì)超過(guò)79個(gè)字符

    This helps users with small displays and makes it possible to have several code files side-by-side on larger displays.
    這個(gè)可以幫助用戶使用小的屏幕展示,并且可以在大屏幕中多個(gè)代碼文件并排展示转晰。

  • Use blank lines to separate functions and classes, and larger blocks of code inside functions.
    使用空行來(lái)隔離開(kāi)函數(shù)和類芦拿,以及函數(shù)里較大的代碼塊。

  • 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).
    在操作符周圍和逗號(hào)后面使用空格蔗崎, 但在括號(hào)里面不需要: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).
    用統(tǒng)一的規(guī)則來(lái)命名類和函數(shù)。一般的慣例是扰藕,類名使用駝峰命名缓苛,函數(shù)和方法使用小寫字母和下劃線〉松睿總是使用self 作為第一個(gè)方法參數(shù)的命名未桥。(更高關(guān)于類和方法請(qǐng)查看:A First Look at Classes for more on classes and methods)

  • 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.
    如果你的代碼要在國(guó)際環(huán)境中使用笔刹,請(qǐng)不要使用花俏的編碼格式。Python默認(rèn)的是UTF8冬耿,即使是空白的ASCII在任何時(shí)候也是最好的舌菜。

  • 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.
    同樣,只要其他不同語(yǔ)言的人有任何機(jī)會(huì)來(lái)閱讀或保存你的代碼淆党,那么不要使用非ASCII字符作為標(biāo)識(shí)符酷师。

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). |

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市染乌,隨后出現(xiàn)的幾起案子山孔,更是在濱河造成了極大的恐慌,老刑警劉巖荷憋,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件台颠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡勒庄,警方通過(guò)查閱死者的電腦和手機(jī)串前,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)实蔽,“玉大人荡碾,你說(shuō)我怎么就攤上這事【肿埃” “怎么了坛吁?”我有些...
    開(kāi)封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)铐尚。 經(jīng)常有香客問(wèn)我拨脉,道長(zhǎng),這世上最難降的妖魔是什么宣增? 我笑而不...
    開(kāi)封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任玫膀,我火速辦了婚禮,結(jié)果婚禮上爹脾,老公的妹妹穿的比我還像新娘帖旨。我一直安慰自己,他們只是感情好灵妨,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布碉就。 她就那樣靜靜地躺著,像睡著了一般闷串。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上筋量,一...
    開(kāi)封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天烹吵,我揣著相機(jī)與錄音碉熄,去河邊找鬼。 笑死肋拔,一個(gè)胖子當(dāng)著我的面吹牛锈津,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凉蜂,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼琼梆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了窿吩?” 一聲冷哼從身側(cè)響起茎杂,我...
    開(kāi)封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纫雁,沒(méi)想到半個(gè)月后煌往,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡轧邪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年刽脖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忌愚。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡曲管,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出硕糊,到底是詐尸還是另有隱情院水,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布癌幕,位于F島的核電站衙耕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏勺远。R本人自食惡果不足惜橙喘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胶逢。 院中可真熱鬧厅瞎,春花似錦、人聲如沸初坠。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)碟刺。三九已至锁保,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爽柒。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工吴菠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人浩村。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓做葵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親心墅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子酿矢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,308評(píng)論 0 10
  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,435評(píng)論 0 23
  • 2018年1月29曰 星期一 今天是這一學(xué)期最后一天正常上課, 兒子感冒還沒(méi)好利索怎燥,考慮到明天考試瘫筐,我們還是...
    萌萌成成媽媽閱讀 268評(píng)論 0 1
  • 我住華山南,君住華山北刺覆; 昨夜一場(chǎng)雨严肪,感覺(jué)近三分。
    木子春閱讀 349評(píng)論 0 0