python快速上手_第三章 函式
def hello():
print('hello')
print('world')
hello()
hello()
hello()
def 關鍵字來定義一個函式, 接下來是 函式名hello() 接下來縮排的部分是 函式體。
函式是在呼叫的時候執行,而不是在定義時執行。
def語句和引數
def hello(name):
print('hello '+name)
hello('Alice')
hello('Mike')
這裡定義了一個hello的函式,有一個名為 name的變元。‘變元’ 是一個變數。 對應於java中的形參。 而我們傳遞的 Alice、Mike 為實參。
返回值和 return語句
return語句包含:
- return關鍵字
- 函式應該返回的值或表示式
import random def getAnswer(answerNumber): if answerNumber == 1: return 'It is 1' elif answerNumber == 2: return 'It is 2' elif answerNumber == 3: return 'It is 3' elif answerNumber == 4: return 'It is 4' elif answerNumber == 5: return 'It is 5' elif answerNumber == 6: return 'It is 6' elif answerNumber == 7: return 'It is 7' elif answerNumber == 8: return 'It is 8' elif answerNumber == 9: return 'It is 9' r = random.randint(1,9) fortune = getAnswer(r) print(fortune)
None值
None 在python中表示 沒有值。None是 NoneType資料型別的唯一值。首字母必須大寫。
等同於其他語言的 null、nil 或者 undefined.
沒有返回值的 函式,預設就是返回 None。比如 print()函式。
對於沒有return語句的函式定義。Python都會在末尾的時候加上 return None. 類似於while或者for迴圈隱式的以 continue語句結尾。
關鍵字引數和 print()
大多數的引數是由它們在函式呼叫中的位置來確定的。而關鍵字引數則是由加在它們簽名的關鍵字來識別的。
關鍵字引數通常用於可選變元。 print()函式有可選的變元 end 和 sep. 分別指定在引數末尾列印什麼,以及在引數之間列印什麼。預設結尾列印的是 換行。
print('hello',end='')
print('world')
helloworld
print('hello','a','b','c',end='',sep=',')
print('world')
hello,a,b,cworld
區域性和全域性作用域
- 全域性作用域中的程式碼不能使用任何區域性變數。
- 但是,區域性作用域可以訪問全域性變數。
- 一個函式的區域性作用域中的程式碼,不能使用其他區域性作用域中的變數。
- 如果在不同的作用域中,你可以用相同的名字命名不同的變數。
區域性變數不能在全域性作用域內使用
def spam():
eggs = 3120
spam()
print(eggs)
上面的程式碼中,在全域性作用域訪問了只在區域性作用域的 eggs。
Traceback (most recent call last):
File "/Users/cuiyonghong/Documents/fiveTimes.py", line 7, in <module>
print(eggs)
NameError: name 'eggs' is not defined
報錯提醒, eggs沒有定義。
區域性作用域不能是喲經其他區域性作用域內的變數
def spam():
eggs = 99
bacon()
print(eggs)
def bacon():
ham = 101
eggs = 0
spam()
99
bacon()函式返回時, bacon的區域性作用域就銷燬了。
一個函式中的區域性變數完全與其他函式中的區域性變數是分開的。
全域性變數可以在區域性作用域中讀取
def spam():
print(eggs)
eggs = 42
spam()
print(eggs)
在 spam()函式中沒有變元名為 eggs, 也沒有程式碼為 eggs 賦值。所以Python認為它是全域性變數 eggs的引用。 所以會打印出 42、
名稱相同的區域性變數和全域性變數
def spam():
eggs = 'spam local'
print(eggs) # spam local eggs變數存在於 spam被呼叫時的區域性作用域
def bacon():
eggs = 'bacon local'
print(eggs) # bacon local eggs變數存在於 bacon被呼叫時的區域性作用域
spam()
print(eggs) # bacon local eggs變數存在於 bacon被呼叫時的區域性作用域
eggs = 'global'
bacon()
print(eggs) #global eggs變數存在於 全域性作用域
global 語句
如果要在一個函式內修改全域性變數,就要使用 global語句。如果在函式的頂部有 global eggs 這樣的程式碼, 就是告訴 Python, “eggs 指向的是全域性變數。不要用這個名字建立一個區域性變數”
def spam():
global eggs
eggs = 'spam'
eggs = 'global'
spam()
print(eggs)
結果
spam
4條法則,來區分一個變數是處於區域性作用域還是全域性作用域:
1.如果變數在全域性作用域中使用(即所有的函式之外),它就總是全域性變數。
2.如果一個函式中,有針對該變數的 global語句, 它就是全域性變數。
3.否則,如果該變數用於函式中的賦值語句,它就是區域性變數。
4.但是,如果該變數沒有用再賦值語句中,它就是全域性變數。
如果要在一個函式中修改全域性變數中儲存的值,就必須要對該變數使用 global語句。
def spam():
print(eggs)
eggs = 'spam'
eggs = 'global'
spam()
print(eggs)
Traceback (most recent call last):
File "/Users/cuiyonghong/Documents/fiveTimes.py", line 8, in <module>
spam()
File "/Users/cuiyonghong/Documents/fiveTimes.py", line 4, in spam
print(eggs)
UnboundLocalError: local variable 'eggs' referenced before assignment
發生這個錯誤的原因是, Python 看到區域性函式中有對 eggs 賦值的語句,因此認為 eggs是一個區域性變數, 但是 在使用前,並沒有對 eggs的申明。所以會報錯。
異常處理
相較與java 中的異常處理。python中的為 try: … except XXxError: …
def spam(divideBy):
return 42/divideBy
print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))
Traceback (most recent call last):
File "/Users/cuiyonghong/Documents/fiveTimes.py", line 8, in <module>
print(spam(0))
File "/Users/cuiyonghong/Documents/fiveTimes.py", line 4, in spam
return 42/divideBy
ZeroDivisionError: division by zero
程式遇到錯誤,就會導致崩潰,並停止執行。 相反,我更希望程式能檢測錯誤,處理錯誤,然後繼續執行。
def spam(divideBy):
try:
return 42/divideBy
except ZeroDivisionError:
print('Error: Invalid a argument')
print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))
使用 try:…except 來捕捉錯誤。並繼續向後執行。