1. 程式人生 > >python快速上手_第三章 函式

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 來捕捉錯誤。並繼續向後執行。