3.1 def語句和參數(shù)
def ...(...)語句用于定義一個(gè)函數(shù),以便后面調(diào)用函數(shù),如:
def hello(name): #定義函數(shù)hello,變元name
? ? print('hello' + name) #打印hello+變元name
namein = input() #定義namein變量,從鍵盤取值并賦給namein
hello(namein) #調(diào)用hello函數(shù),將namein的變量賦值給變元name。
需注意:函數(shù)被調(diào)用并返回后,在變元中的值就丟失了。
3.2 返回值和return語句
def語句創(chuàng)建函數(shù)時(shí),可以用return語句指定應(yīng)該返回什么值,如
import random
def getAnswer(answerNumber): #定義一個(gè)函數(shù)getAnswer,變元answerNumber
? ? if answerNumber == 1:
? ? ? ? return 'It is certain' #當(dāng)變元為1時(shí),打印這個(gè)結(jié)果,下述同理。
? ? elif answerNumber == 2:
? ? ? ? return 'It is decidedly so'
? ? elif answerNumber == 3:
? ? ? ? return 'Yes'
? ? elif answerNumber == 4:
? ? ? ? return 'Reply hazy try again'
? ? elif answerNumber == 5:
? ? ? ? return 'Ask again later'
? ? elif answerNumber == 6:
? ? ? ? return 'Concertrate and ask again'
? ? elif answerNumber == 7:
? ? ? ? return 'My reply is no'
? ? elif answerNumber == 8:
? ? ? ? return 'Outlook not so good'
? ? elif answerNumber == 9:
? ? ? ? return 'Very doubtful'
r = random.randint(1, 9) #定義變量r,調(diào)用內(nèi)建函數(shù)random,其范圍是1到9
fortune = getAnswer(r) #運(yùn)行自建函數(shù)getAnswer,變元值為r。
print(fortune) #打印fortune中的存儲結(jié)果
3.3 None值
None表示沒有值,是NoneType數(shù)據(jù)類型的唯一值。
注意,print()函數(shù)是沒有返回值的,與none值相同。
可以通過:
spam = print('Hello')
None == spam
#返回結(jié)果為True得出。
3.4關(guān)鍵字參數(shù)和print()
關(guān)鍵字是由在調(diào)用函數(shù)時(shí)選用的,通常用于可選變元。
如print中的 end、, 、seq函數(shù)。
#end=''
print('Hello',end=' ')
print('World')
結(jié)果→→Hello World
# ','
print('Cat','Dog','Mice')
結(jié)果→→Cat Dog Mice
# seq = ''
print('Cat','Dog','Mice',sep=',')
結(jié)果→→Cat,Dog,Mice
3.5 局部和全局作用域
全局指在本程序中一直生效,局部是指在程序的某一個(gè)局部中生效,如果退出局部則失效。
def spam():
? ? eggs = 99 #局部變量1
? ? bacon() #此處局部變量2會被打印,對于spam()來說,這里就是局部
? ? print(eggs) #此處打印結(jié)果為99,因?yàn)閎acon()執(zhí)行后,bacon()中的局部變量失效了
def bacon():
? ? ham = 101
? ? eggs = 0 #局部變量2
spam()
bacon()
全局變量可以和局部變量重名,但我們盡量讓他們之間不要重名。
***
def spam():
? ? print(eggs)
eggs = 42 #全局變量1
spam()
print(eggs)
上代碼中的局部變量eggs在
打印時(shí)引用了全局變量。
總結(jié):全局會被局部引用,局部不會被全局引用,要想運(yùn)行輕松點(diǎn),就要注意別重名啦。
3.6 global語句
為函數(shù)命名時(shí)加上global語句如“global eggs = 1”,就可以讓python知道在這代碼全局中所有的eggs函數(shù)都值都為1。
函數(shù)中一個(gè)人變量要么總是全局變量,要么總是局部變量。
3.7 異常處理
由于你不知道用戶輸入的變元是什么,所以你需要在他們執(zhí)行前執(zhí)行一次檢查,以免程序直接出錯(cuò)跳出。
#CODE
def spam(divideBy):
? ? try:
? ? ? ? return 42 / divideBy
? ? except ZeroDivisionError:
? ? ? ? print('錯(cuò)誤:無效輸入')
print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))
#OUTPUT
21.0
3.5
錯(cuò)誤:無效輸入
None
42.0
3.8 猜數(shù)字游戲
#This is a guess number game.
import random
SecretNumber = random.randint(1,20)
print('I have a number, come on and guess.')
#print('PLZ enter a number.')
#Ask the player to guess 6 times.
for guessesTaken in range(1,7):
? ? print('PLZ enter a number.')
? ? guess = int(input())
? ? if guess < SecretNumber:
? ? ? ? print('Your number is too low.')
? ? elif guess > SecretNumber:
? ? ? ? print('Your number is too high.')
? ? else:
? ? ? ? break # This condition is the correct guess!
if guess == SecretNumber:
? ? print('Good job! You guessed my number in ' + str(guessesTaken) + ' times.')
else:
? ? print('Nope. The number I was thinking of was ' + str(SecretNumber))
3.9 本章習(xí)題
1.為什么在程序中加入函數(shù)會有好處??
????函數(shù)快,可以消除重復(fù),讓代碼更短,讀起來也更容易。
2.函數(shù)中的代碼何時(shí)執(zhí)行:在函數(shù)被定義時(shí),還是在函數(shù)被調(diào)用時(shí)?
????在函數(shù)被調(diào)用時(shí)執(zhí)行。
3.什么語句創(chuàng)建一個(gè)函數(shù)?
? ? def語句創(chuàng)建函數(shù)。
4.一個(gè)函數(shù)和一次函數(shù)調(diào)用有什么區(qū)別?
????函數(shù)是一個(gè)開頭為def的語句,它包含函數(shù)名和函數(shù)體。如def guess()
????而函數(shù)之后的guess()是一次函數(shù)調(diào)用,只有當(dāng)代碼執(zhí)行到guess()時(shí),才會調(diào)用函數(shù)def guess()下面的函數(shù)體。
5.Python 程序中有多少全局作用域?有多少局部作用域?
? ? 在調(diào)用函數(shù)時(shí),創(chuàng)建了一個(gè)全局作用域和一個(gè)局部作用域。
6.當(dāng)函數(shù)調(diào)用返回時(shí),局部作用域中的變量發(fā)生了什么?
? ? 清空。
7.什么是返回值?返回值可以作為表達(dá)式的一部分嗎?
? ? 返回值即函數(shù)執(zhí)行結(jié)束后的返回結(jié)果,他可以作為表達(dá)式的一部分。
8.如果函數(shù)沒有返回語句,對它調(diào)用的返回值是什么?
? ? None
9.如何強(qiáng)制函數(shù)中的一個(gè)變量指的是全局變量?
? ? global xxx 則 xxx 被強(qiáng)制為一個(gè)全局變量。
10.None 的數(shù)據(jù)類型是什么?
? ? none.type
11.import areallyourpetsnamederic 語句做了什么?
? ? 導(dǎo)入了一個(gè)名為areallyourpetsnamederic的函數(shù),
12.如果在名為 spam 的模塊中,有一個(gè)名為 bacon()的函數(shù),在引入 spam 后,如何調(diào)用它?
? ? spam.bacon()
13.如何防止程序在遇到錯(cuò)誤時(shí)崩潰?
? ? try
? ? except
????函數(shù)進(jìn)行驗(yàn)證
14.try 子句中發(fā)生了什么?except 子句中發(fā)生了什么?
? ? try句子中運(yùn)行了你的表達(dá)式,如果產(chǎn)生錯(cuò)誤,則轉(zhuǎn)到except。
? ? 之后程序照常運(yùn)行。
3.11 代碼實(shí)踐
3.11.1?
編寫一個(gè)名為 collatz()的函數(shù),它有一個(gè)名為 number 的參數(shù)。如果參數(shù)是偶數(shù),那么 collatz()就打印出 number // 2,并返回該值。如果 number 是奇數(shù),collatz()就打印并返回 3 * number + 1。
然后編寫一個(gè)程序,讓用戶輸入一個(gè)整數(shù),并不斷對這個(gè)數(shù)調(diào)用 collatz(),直到函數(shù)返回值1(令人驚奇的是,這個(gè)序列對于任何整數(shù)都有效,利用這個(gè)序列,你遲早會得到 1!既使數(shù)學(xué)家也不能確定為什么。你的程序在研究所謂的“Collatz序列”,它有時(shí)候被稱為“最簡單的、不可能的數(shù)學(xué)問題”)。
記得將 input()的返回值用 int()函數(shù)轉(zhuǎn)成一個(gè)整數(shù),否則它會是一個(gè)字符串。 提示 如果 number % 2 == 0,整數(shù) number 就是偶數(shù),如果 number % 2 == 1,它就是奇數(shù)。
這個(gè)程序的輸出看起來應(yīng)該像這樣:
Enter number:
3
10
5
16
8
4
2
1
def collatz(dd):
? ? global number
? ? number = dd
? ? while number != 1:
? ? ? ? if number % 2 == 0:
? ? ? ? ? ? number = number // 2
? ? ? ? ? ? print(number)
? ? ? ? elif number % 2 == 1:
? ? ? ? ? ? number = number * 3 + 1
? ? ? ? ? ? print(number)
3.11.2
在前面的項(xiàng)目中添加 try 和 except 語句,檢測用戶是否輸入了一個(gè)非整數(shù)的字符串。正常情況下,int()函數(shù)在傳入一個(gè)非整數(shù)字符串時(shí),會產(chǎn)生 ValueError 錯(cuò)誤,比如 int('puppy')。在 except 子句中,向用戶輸出一條信息,告訴他們必須輸入一個(gè)整數(shù)。
try:
? ? nm1 = int(input('請輸入一個(gè)數(shù)字\n'))
except ValueError:
? ? print('請輸入正確的數(shù)字!')
else:
? ? print(collatz(nm1))