若是沒有看基礎部分第一章,請前往Python基礎知識兩部曲:一java
1. 無參數的函數: def greet_user(): """顯示簡單的函數體""" print("Hello Python") greet_user() 獲得: Hello Python 2. 有參數的函數: def greet_user(username): """顯示簡單的函數體""" print("Hello Python: "+username) greet_user('kobe') 獲得: Hello Python: kobe
在函數greet_user()中,變量username是一個形參---函數完成其工做所須要的一項信息.在代碼greet_user('kobe')中,值'kobe'是一個實參。python
須要注意參數的位置程序員
def describe_pet(animal_type,pet_name): print("\nI have a " + animal_type + ".") print("My "+ animal_type + "'s name is "+pet_name.title()+".") describe_pet('dog','james') describe_pet('dog','iverson') 獲得: I have a dog. My dog's name is James. I have a dog. My dog's name is Iverson.
關鍵字實參是傳遞給函數的名稱-值對,直接在實參中將名稱和值關聯起來,所以向函數傳遞實參時不會混淆。與參數順序無關。json
def describe_pet(animal_type,pet_name): print("\nI have a " + animal_type + ".") print("My "+ animal_type + "'s name is "+pet_name.title()+".") describe_pet(pet_name = 'kkkk',animal_type = 'cat') 獲得: I have a cat. My cat's name is Kkkk.
編寫函數能夠給每一個形參指定默認值,app
# 注意已經設置了默認值的參數要放在後面, def describe_pet2(pet_name,animal_type = 'dog'): print("\nI have a " + animal_type + ".") print("My "+ animal_type + "'s name is "+pet_name.title()+".") describe_pet2('kobe') describe_pet2(pet_name = 'james') 獲得: I have a dog. My dog's name is Kobe. I have a dog. My dog's name is James.
調用返回值的函數時,須要提供一個變量,用於存儲返回的值。dom
def get_formatted_name(first_name,last_name): """返回整潔的姓名""" full_name = first_name + '-' +last_name return full_name.title() musician = get_formatted_name('kobe','bryant') print(musician) 獲得: Kobe-Bryant
def get_formatted_name(first_name,last_name,middle_name= ''): """返回整潔的姓名""" if middle_name: full_name = first_name +'-'+middle_name+'-'+last_name else: full_name = first_name + '-' +last_name return full_name.title() musician = get_formatted_name('kobe','bryant') print(musician) musician = get_formatted_name('kobe','bryant','vboy') print(musician) 獲得: Kobe-Bryant Kobe-Vboy-Bryant
def build_person(first_name,last_name,age = ''): """返回一個字典,其中包含有關一我的的信息""" person = {'first':first_name,'last':last_name} if age: person['age'] = age pass return person musician = build_person('kobe','bryant',23) print(musician) 獲得: {'age': 23, 'last': 'bryant', 'first': 'kobe'}
ef get_formatted_name(first_name,last_name,middle_name= ''): """返回整潔的姓名""" if middle_name: full_name = first_name +'-'+middle_name+'-'+last_name else: full_name = first_name + '-' +last_name return full_name.title() while True: print("\nPlease tell me you name:") first_name = input("first Name: ") last_name = input("last Name: ") formatted_name = get_formatted_name(first_name,last_name) print(formatted_name) msg = input("do you want to exit (Y/N)") if msg.upper() == 'Y': break 終端運行獲得: liukingdeMacBook-Pro:desktop liuking$ python3 input.py Please tell me you name: first Name: kobe last Name: bryant Kobe-Bryant do you want to exit (Y/N)n Please tell me you name: first Name: chris last Name: paul Chris-Paul do you want to exit (Y/N)y liukingdeMacBook-Pro:desktop liuking$
# 沒有使用函數是這樣的。 """將未確認的用戶,進行認證。""" unconfirmed_users = ['one','two','three'] confirmed_users = [] while unconfirmed_users: """處理用戶認證操做""" current_user = unconfirmed_users.pop() print("verifying User:"+current_user) confirmed_users.append(current_user) """打印認證用戶""" print("\nThe following users have been confirmed: ") for user in confirmed_users: print(user.title()) 獲得: verifying User:three verifying User:two verifying User:one The following users have been confirmed: Three Two One
unconfirmed_users = ['first','second','third'] confirmed_users = [] """處理用戶認證操做""" def deal_verify_user(unconfirmed_users,confirmed_users): while unconfirmed_users: """處理用戶認證操做""" current_user = unconfirmed_users.pop() print("verifying User:"+current_user) confirmed_users.append(current_user) def print_verify_user(confirmed_users): for user in confirmed_users: print(user.title()) deal_verify_user(unconfirmed_users,confirmed_users) print("\nThe following users have been confirmed: ") print_verify_user(confirmed_users) 獲得: verifying User:third verifying User:second verifying User:first The following users have been confirmed: Third Second First
上面咱們發現獲得同樣的結果,但使用了函數處理能夠作到複用,且邏輯比較清晰,易於擴展。ide
若是咱們像備份以前的數據,咱們就不能修改未認證的用戶,這個時候咱們能夠用切片來處理咱們的操做了。函數
unconfirmed_users = ['first','second','third'] confirmed_users = [] """處理用戶認證操做""" def deal_verify_user(unconfirmed_users,confirmed_users): while unconfirmed_users: """處理用戶認證操做""" current_user = unconfirmed_users.pop() print("verifying User:"+current_user) confirmed_users.append(current_user) def print_user(confirmed_users): for user in confirmed_users: print(user.title()) """這裏咱們將列表的副本傳給函數,列表的原始數據不會被修改""" deal_verify_user(unconfirmed_users[:],confirmed_users) print("\nThe following users have been confirmed: ") print_user(confirmed_users) print("\n展現原始數據: ") print_user(unconfirmed_users) 獲得: verifying User:third verifying User:second verifying User:first The following users have been confirmed: Third Second First 展現原始數據: First Second Third
有的時候咱們不知道函數須要接受多少個實參,python容許函數從調用語句中收集任意數量的實參。工具
「」「這裏*toppons指定了一個空元組,將收到的全部值都封裝在這個這元組中。」「」 def make_pizza(*toppons): """打印顧客點的全部配料""" print("\nMaking a pizza with the following toppings") for top in toppons: print("- "+top.title()) make_pizza('pepperoni') make_pizza('pepperoni','green peppers','extra cheese') 獲得: Making a pizza with the following toppings - Pepperoni Making a pizza with the following toppings - Pepperoni - Green Peppers - Extra Cheese
若是要讓函數接受不一樣類型的實參,必須在函數定義中接納任意數量實參的形參放在最後。python先匹配位置實參和關鍵字實參,再匹配任意實參,*因此這裏咱們把make_pizza(size,toppons),位置實參在前,任意實參在後。**單元測試
def make_pizza(size,*toppons): """打印顧客點的全部配料""" print("\nMaking a " + str(size) +"-inch pizza with the following toppings") for top in toppons: print("- "+top.title()) make_pizza(18,'pepperoni') make_pizza(33,'pepperoni','green peppers','extra cheese') 獲得: Making a 18-inch pizza with the following toppings - Pepperoni Making a 33-inch pizza with the following toppings - Pepperoni - Green Peppers - Extra Cheese
有時候須要接受任意數量的實參,但預先不知道傳遞給函數的會是什麼樣的信息。在這種狀況下,可將函數編寫成可以接受任意數量鍵值對---調用語句提供了多少就接愛多少。
def build_profile(first,last,**user_info): """建立一個字典""" profile = {} profile['first_name'] = first profile['last_name'] = last for key,value in user_info.items(): profile[key] = value return profile info = build_profile('Kobe','bryant',like = 'ball',age = 35) print(info) 獲得: {'first_name': 'Kobe', 'last_name': 'bryant', 'age': 35, 'like': 'ball'}
函數的優勢之一是,使用它們可將代碼塊與主程序分離,經過給函數指定描述性名稱,可以讓主程序容易得多。還能夠更進一步,將函數存儲在被稱爲模塊的獨立文件中,再將模塊導入到主程序中。import語句容許在當前運行的程序文件中使用模塊代碼。
經過將函數存儲在獨立的文件中,可隱藏程序代碼的細節,將重點入在程序的高層邏輯上,還能讓你在衆多不一樣的程序中重用函數。將函數存儲在獨立文件後,可與其它程序員共享這些文件而不是整個程序。知道如何導入函數,還能讓你使用其它程序員編寫的函數庫。
使用import語句導入了名爲module_name.py的整個模塊,就可以使用下面的語法來使用其中任何一個函數。
module_name.function_name()<br/>
下面咱們建立一個input.py文件。
def make_pizza(size,*toppons): """打印顧客點的全部配料""" print("\nMaking a " + str(size) +"-inch pizza with the following toppings") for top in toppons: print("- "+top.title())
再建立一個test_input.py文件
import input input.make_pizza(18,'pepperoni') input.make_pizza(33,'pepperoni','green peppers','extra cheese') 獲得: Making a 18-inch pizza with the following toppings - Pepperoni Making a 33-inch pizza with the following toppings - Pepperoni - Green Peppers - Extra Cheese
上面咱們使用import 導入input文件。而後使用文件名input,再調用函數。
#####2.導入特定的函數。
還能夠導入模塊中特寫的函數,這種導入方法的語法以下:from module_name import function_name
from module_name import function_0,function_1,function_2
對於只想導入要使用的函數,代碼將相似於下面這樣:
使用這種語法,調用函數時就無需使用句點,因爲咱們在import語句中顯示地導入了函數make_pizza,所以調用它時只須要指定其名稱。
from input import make_pizza make_pizza(18,'pepperoni') make_pizza(33,'pepperoni','green peppers','extra cheese') 能夠獲得一樣的效果。
有的時候要導入的函數名稱可能與程序中現有的名稱衝突,或者函數名稱太長,可指定簡短而獨一無二的別名---函數的另外一個名稱,相似於外號。
指定別名的通用語法是:from module_name import function_name as fn
下面咱們能夠把上面代碼修改一下:
from input import make_pizza as mp mp(18,'pepperoni') mp(33,'pepperoni','green peppers','extra cheese')
還能夠給模塊指定別名。給模塊指定別名通用語法以下:<br/>import module_name as mn<br/>
代碼以下:
import input as put put.make_pizza(18,'pepperoni') put.make_pizza(33,'pepperoni','green peppers','extra cheese')
使用星號() 運算符可讓Python導入模塊中全部的函數:
`from module_name import `
首先建立有兩個函數的文件:
def make_pizza(size,*toppons): """打印顧客點的全部配料""" print("\nMaking a " + str(size) +"-inch pizza with the following toppings") for top in toppons: print("- "+top.title()) def make_KFC(size,*toppons): """打印顧客點的全部配料""" print("\nMaking a " + str(size) +"-inch KFC with the following toppings") for top in toppons: print("- "+top.title())
再調用:
from input import * make_pizza(33,'pepperoni','green peppers','extra cheese') make_KFC(33,'pepperoni','green peppers','extra cheese') 獲得: Making a 33-inch pizza with the following toppings - Pepperoni - Green Peppers - Extra Cheese Making a 33-inch KFC with the following toppings - Pepperoni - Green Peppers - Extra Cheese
注意:import語句中星號讓Python將模塊中每一個函數都複製到這個程序文件中,因爲導入了每一個函數,可經過名稱來調用每一個函數,而無需使用句點表示法。但使用並不是本身編寫的大型模塊時,最好不要採用這種導入方法:若是模塊中有函數的名稱與你項目的中使用的名稱相同,可能致使意想不到的結果:Python可能遇到多個名稱相同的函數或變量,進而覆蓋函數,而不是分別導入全部的函數。
最佳作法:要麼只導入你須要使用的函數,要麼導入整個模塊並使用句點表示法。這能讓代碼更清晰,更容易理解和閱讀。
編寫函數時,須要牢記幾個細節:應給函數指定描述性名稱,且只在其中使用小寫字母和下劃線,描述性名稱可幫助你和別人明白代碼想要什麼,給模塊命名時也應按上述約定。
給形參指定默認值時,等號兩邊不要有空格。
def function_name(parameter_0,parameter_1='devault value')
對於函數調用中的關鍵字實參,
function_name(value_0,parameter='value')
完
全部的面向對象編輯思想都是同樣的,因此這一篇對因而程序員的你必定是很是簡單的.
class Car(): """一次模擬汽車的簡單嘗試""" def __init__(self, make, model, year): self.make = make self.model = model self.year = year self.odometer_reading = 0 def get_descriptive_name(self): long_name = str(self.year) + ' ' + self.make + ' ' + self.model return long_name.title() def update_odometer(self, mileage): if mileage >= self.odometer_reading: self.odometer_reading = mileage else: print("you can't roll back an odometer!")
這裏面我就建立了一個一個Car類,不要問我爲何這麼寫,這就是約定。
代碼說明def __init__(self, make, model, year):
- 這是一個特殊的函數,使用兩個下劃線標記主要是爲了跟其它的普通函數區分開來。 在java裏這個叫構造函數
- 裏面有帶了幾個參數來填充屬性,還能夠添加默認參數,裏面我添加了一個odometer_reading這個屬性
- 這裏面我添加了兩個方法get_descriptive_name 和 update_odometer 這裏面必須傳入self,這是對自身的一種引用,另外還能夠在後面添加若干參數。
使用類:
byd = Car('byd','byd tang','2017') #實例化Car類 str1 = byd.get_descriptive_name() # 調用類的方法 print(str1.title()) 獲得結果 2017 Byd Byd Tang 再調用一個帶參數的方法 byd.update_odometer(100); print('move '+str(byd.odometer_reading)+' miles') 獲得結果: move 100 miles
直接在Car這個文件裏再寫一個子類,電動車類:
class ElectriCar(Car): #繼承Car類 """電動汽車獨特之處""" def __init__(self, make, model, year, battery_size=100): """初始化父類的屬性""" super().__init__(make, model, year) #這裏繼承父類的屬性 和java裏的super方法同樣 self.battery_size = battery_size # 子類有本身的屬性 def descript_batter(self): print("This car has a " + str(self.battery_size) + " kwh battery.") def fill_gas_tank(self): print("i hava a battery") my_tesla = ElectriCar('tesla', 'model s', '2016') print(my_tesla.get_descriptive_name()) #引用父類的描述方法 print(my_tesla.fill_gas_tank()) #重寫子類的電池方法 獲得結果: 2016 Tesla Model S i hava a battery
代碼說明
####9.3 導入類
####9.4 Python標準庫
異常是使用try-except代碼塊處理的。try-except代碼塊讓Python執行指定的操做,同時告訴Python發生異常時怎麼辦。使用了try-except代碼塊時,即使出現異常,程序也將繼續運行:顯示你編寫的友好的錯誤信息,而不是令用戶迷惑的traceback.
print(5/0)
當你認爲可能發生了錯誤時,可編寫一個try-except代碼塊來處理可能引起的異常。
處理ZeroDivisionError異常的try-except代碼塊相似於下面這樣:
try: print(5/0) except Exception, e: print("You can't divide by zero!")
若是程序出現異常,就執行print("You can't divide by zero!"),再也不是traceback:
發生錯誤時,若是程序還有工做沒有完成,妥善處理錯誤就尤爲重要。這種狀況常常會現出如今要求用戶提供輸入的程序中;若是程序可以妥善地處理無效輸入,就能再提示用戶提供有效輸入,而不至於崩潰。
下面來一個只執行除法的簡單計算器:
print("Give me two numbers, and I'll divide them.") print("Enter 'q' to quit. ") while True: first_number = input("\nFirst number: ") if first_number == 'q': break; second_number = input("\nSecond number: ") if second_number == 'q': break; answer = int(first_number)/int(second_number) print(answer) 獲得: liukingdeMacBook-Pro:desktop liuking$ python3 input.py Give me two numbers, and I'll divide them. Enter 'q' to quit. First number: 4 Second number: 2 2.0 First number: 4 Second number: g Traceback (most recent call last): File "input.py", line 244, in <module> answer = int(first_number)/int(second_number) ValueError: invalid literal for int() with base 10: 'g' liukingdeMacBook-Pro:desktop liuking$
經過將可能引起錯誤的代碼放在try-except代碼塊中,可提升這個程序抵禦錯誤的能力,錯誤是是執行除法運算的代碼行致使的,所以咱們須要將它放到try-except代碼塊中。依賴於try代碼塊成功執行的代碼都放到else代碼塊中:
print("Give me two numbers, and I'll divide them.") print("Enter 'q' to quit. ") while True: first_number = input("\nFirst number: ") if first_number == 'q': break; second_number = input("\nSecond number: ") if second_number == 'q': break; try: answer = int(first_number)/int(second_number) except Exception: print("you can't divide by 0!") else: print(answer) 獲得: liukingdeMacBook-Pro:desktop liuking$ python3 input.py Give me two numbers, and I'll divide them. Enter 'q' to quit. First number: 5 Second number: 3 1.6666666666666667 First number: 5 Second number: 0 you can't divide by 0! First number:
發現異常也能友好的提示給用戶。
try-except-else代碼塊的工做原理大體以下:python嘗試執行try代碼塊中的代碼;只有可能引起異常的代碼才須要放在try語句中。有時候,有一些僅在try代碼塊成功執行時才須要運行的代碼,這些代碼應該放在else代碼塊中。except代碼塊告訴python,若是它嘗試運行try代碼塊中的代碼時引起了指定的異常,該怎麼辦。
經過預測可能發生錯誤的代碼,可編寫健壯的程序,它們即使面臨無效數據或者缺乏資源,也能繼續運行,從而可以抵禦無心的用戶錯誤和惡意的***。
通常都是使用模塊json來存儲數據。
使用json.dump()來存儲(寫入)數據
import json numbers = [2,3,5,7,9,22,44] file_name = 'numbers.json' with open(file_name,'w') as f_obj: json.dump(numbers,f_obj)
咱們先要導入模塊json,再執行,最後能夠打開numbers.json文件,看到其內容與python中同樣。
再使用json.load()讀取numbers.json文件:
import json file_name = 'numbers.json' with open(file_name) as f_obj: numbers = json.load(f_obj) print(numbers) 獲得: [2, 3, 5, 7, 9, 22, 44]
與咱們指望的一致。
Python標準庫中的模塊unitest提供了代碼測試工具。單元測試用於測試函數的某個方面是否有問題;測試用例是一組單元測試,這些單元測試一塊兒覈實函數在各類情形下的行爲都符合要求。
#####2.可經過的測試
要爲函數編寫測試用例,可先導入模塊unittest以及要測試的函數,再建立一個繼承unittest.TestCase的類,並編寫一系列方法對函數行爲的不一樣方面進行測試。
首先咱們來寫一個方法:
def get_formatted_name(first,last): """Generate a neatly formatted full name.""" full_name = first + ' ' + last return full_name.title()
再寫一個測試用例
import unittest from name_function import get_formatted_name class NameTestCase(unittest.TestCase): """測試name_function.py""" def test_first_last_name(self): """可以正確地處理Janis Joplin這樣的姓名嗎?""" formatted_name = get_formatted_name('janis','joplin') self.assertEqual(formatted_name,'Janis Joplin') unittest.main() 獲得: . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK
這裏咱們給出一個不能經過測試的案例
def get_formatted_name(first,middle,last): """Generate a neatly formatted full name.""" full_name = first + ' ' + middle + ' ' + last return full_name.title() 再運行一下: E ====================================================================== ERROR: test_first_last_name (__main__.NameTestCase) 可以正確地處理Janis Joplin這樣的姓名嗎? ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/liuking/Desktop/test_name_function.py", line 11, in test_first_last_name formatted_name = get_formatted_name('janis','joplin') TypeError: get_formatted_name() takes exactly 3 arguments (2 given) ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1) [Finished in 0.1s with exit code 1]
測試未經過時怎麼辦?若是檢查的條件沒錯,測試經過了意味着函數的行爲是對的,而測試未經過意味着你編寫的新代碼有錯,所以測試未經過時,不要修改測試,而應修復致使測試不能經過的代碼:檢查剛對函數所作的修改,找到致使函數行爲不符合預期的修改。
把剛纔的函數代碼稍做修改:
def get_formatted_name(first,last,middle = ''): """Generate a neatly formatted full name.""" if middle: full_name = first + ' ' + middle + ' ' + last else: full_name = first + ' ' + last return full_name.title() 獲得: . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK [Finished in 0.1s]
又能正確經過測試。
咱們爲NamesTestCase再添加一個方法:
# -*- coding: utf8 -*- import unittest from name_function import get_formatted_name class NameTestCase(unittest.TestCase): """測試name_function.py""" def test_first_last_name(self): """可以正確地處理Janis Joplin這樣的姓名嗎?""" formatted_name = get_formatted_name('janis','joplin') self.assertEqual(formatted_name,'Janis Joplin') def test_first_last_middle_name(self): """可以正確地處理Janis Joplin Kobe這樣的姓名嗎?""" formatted_name = get_formatted_name('janis','Kobe','joplin') self.assertEqual(formatted_name,'Janis Joplin Kobe') unittest.main() 獲得: .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK [Finished in 0.1s]
經常使用的斷言方法,使用這些方法可覈實返回的值等於或不等於預期的值,返回的值爲True或False,返回的值在列表中或者不在列表中。只能在繼承unittest.TestCase的類中使用這些方法
方法 | 用途 |
---|---|
assertEqual(a,b) | 覈實 a ==b |
assertNotEqual(a,b) | 覈實 a !=b |
assertTrue(x) | 覈實x爲True |
assertFalse(x) | 覈實x爲False |
assertIn(item,list) | 覈實item在list中 |
assertNotIn(item,list) | 覈實item不在list中 |
類的測試與函數的測試類似--你所作的大部分工做都是測試類中方法的行爲,但存在一些不一樣之處,
# -*- coding: utf8 -*- class AnonymousSurvey(): """收集匿名調查問卷的答案""" def __init__(self, question): self.question = question self.responses = [] def show_question(self): """顯示調查問卷""" print(self.question) def store_response(self,new_response): """存儲單份調查問卷""" self.responses.append(new_response); def show_results(self): """顯示收集到的全部答案""" print("Survey Results:") for response in self.responses: print('- '+response) ------------------------------------------------------------------------------------------ from survey import AnonymousSurvey #定義一人問題,並建立一個表示調查的AnonymousSurvey對象 question = "What language did you first learn to speak?" my_survey = AnonymousSurvey(question) my_survey.show_question() print("Enter 'q' at any time to quit.\n") while True: response = input("language: ") if response == 'q': break my_survey.store_response(response) #顯示調查結果: print("\nThank you to everyone who participated in the survey?") my_survey.show_results() 運行獲得: 在終端運行獲得: What language did you first learn to speak? Enter 'q' at any time to quit. language: english language: chinese language: japanese language: q Thank you to everyone who participated in the survey? Survey Results: - english - chinese - japanese
下面來編寫一個測試,對AnonymousSurvey類的行爲的一個方面進行驗證:若是用戶面對調查問題時只提供一個答案,這個答案也能被妥善保存,爲此咱們將在這個答案被保存後,用方法assertIn()來覈實包含在答案列表中:
import unittest from survey import AnonymousSurvey class TestAnonymousSurvey(unittest.TestCase): """docstring for ClassName""" def test_store_single_response(self): question = "what language did you first learn to speak?" my_survey = AnonymousSurvey(question) my_survey.store_response('english') self.assertIn('english',my_survey.responses) unittest.main() 運行獲得: . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK [Finished in 0.1s]
這裏咱們首先導入了模塊unittest以及要測試的類AnonymousSurvey,它也繼承於unittest.TestCase第一個測試方法驗證調查問題的單個答案被存儲後,會包含在調查結果列表中。
只能收集一個答案的調查用途不大,咱們來覈實用戶提供的三個答案,也將它們存儲。
import unittest from survey import AnonymousSurvey class TestAnonymousSurvey(unittest.TestCase): """docstring for ClassName""" def test_store_single_response(self): question = "what language did you first learn to speak?" my_survey = AnonymousSurvey(question) my_survey.store_response('english') self.assertIn('english',my_survey.responses) def test_store_three_responses(self): question = "what language did you first learn to speak?" my_survey = AnonymousSurvey(question) responses = ['english','chinese','japanese'] for response in responses: my_survey.store_response(response) for response in responses: self.assertIn(response,my_survey.responses) unittest.main() 運行獲得: .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK [Finished in 0.1s]
在unittest.TestCase類包含方法setUp(),讓咱們只須要建立這些對象一次,並在每一個測試方法中使用他們,若是你在TestCase類中包含了方法setUp(),Python將先運行它,再運行各個以test_打頭的方法,這樣在咱們編寫的每一個測試方法中均可使用方法setUp()中建立的對象。
# -*- coding:utf8 -*- import unittest from survey import AnonymousSurvey class TestAnonymousSurvey(unittest.TestCase): def setUp(self): """建立一個調查對象和一組答案,供使用的測試方法使用。""" question = "What language did you first learn to speak?" self.my_survey = AnonymousSurvey(question) self.responses = ['chinese','english','japanese'] """docstring for ClassName""" def test_store_single_response(self): self.my_survey.store_response(self.responses[0]) self.assertIn(self.responses[0],self.my_survey.responses) def test_store_three_responses(self): for response in self.responses: self.my_survey.store_response(response) for response in self.responses: self.assertIn(response,self.my_survey.responses) unittest.main() 運行獲得: .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK [Finished in 0.1s]
方法setUp()讓測試方法編寫起來更容易,可在setUp()方法中建立一系列並設置他們的屬性,再在測試方法中直接使用這些實例,相比於在每一個測試方法中都都建立並設置其屬性,這要容易得多。