《Head First Python》第六章--定制数据对象
先上數據集:Head First Python 數據集
第六章的數據在第五章的基礎上加了兩個屬性:姓名和出生日期
james2.txt
James Lee,2002-3-14,2-34,3:21,2.34,2.45,3.01,2:01,2:01,3:10,2-22,2-01,2.01,2:16????上一章的思路依然沒有問題,還是按照逗號拆分成列表,不過需要多出兩個變量來保存姓名和出生日期。如果對每個運動員都創建兩個變量,四個運動員就是8個變量,10個運動員就得20個變量,這并不合理。而且這些數據之間是有聯系的,它們都跟同一個人相關,列表也無法體現這種關聯性。
? ? 方法一:數據字典
? ? 首先我們采用Python內置的一種數據結構:字典,字典將鍵與數據相關聯,可以使內存中的數據和實際數據的結構保持一致。
? ? 創建字典的兩種方式:
????????一、james = {}
????? ? 二、james = dict()
? ? james['name'] = 'James Lee'? ?這就是字典中的一個鍵值對
下面是本章的第一種數據處理方法:
# 格式化字符串 def sanitize(time_string):if('-' in time_string):splitter = '-'elif(':' in time_string):splitter = ':'else:return (time_string)(mins, secs) = time_string.split(splitter)return (mins + '.' + secs)# 從文件讀取訓練數據 def get_coach_data(filename):# 創建一個字典接受返回值mydic = {}try:with open(filename) as myfile:# 把讀到的數據按','分隔成一個列表data = myfile.readline().strip().split(',')# 取前兩個數據(pop(0)刪除并返回最前面的數據項)mydic['name'] = data.pop(0)mydic['DOB'] = data.pop(0)# 對后面的數據進行格式化,并取最小的三個數據mydic['top3'] = str(sorted(set([sanitize(d) for d in data]))[0:3])except IOError as ioerr:# 文件異常print('File Error: ' + str(ioerr))return (None)# 返回字典return (mydic)# 輸出james的最好的三次數據 james = get_coach_data('james2.txt') print(james['name'] + "`s faster times are : " + james['top3'])# 輸出julie的最好的三次數據 julie = get_coach_data('julie2.txt') print(julie['name'] + "`s faster times are : " + julie['top3'])# 輸出mikey的最好的三次數據 mikey = get_coach_data('mikey2.txt') print(mikey['name'] + "`s faster times are : " + mikey['top3'])# 輸出sarah的最好的三次數據 sarah = get_coach_data('sarah2.txt') print(sarah['name'] + "`s faster times are : " + sarah['top3'])運行結果如圖:
方法二:定義一個類,利用類對象來體現數據結構關系
? ? Python使用class定義類。每個定義的類都有一個特殊的方法,名為__init__(),可以通過這個方法控制如何初始化對象。
? ? 類中的和函數的定義類似,同樣是使用def來定義。
? ? Python要求每個方法的第一個參數為調用對象實例,也就是說每個方法的第一個參數都是self。
這樣我們就可以對運動員數據進行封裝:
class Athlete:# 構造方法,至少要提供一個name值def __init__(self, a_name, a_dob=None, a_times=[]):self.name = a_nameself.dob = a_dobself.times = a_times# 獲取最快的三次記錄def top3(self):return (str(sorted(set([sanitize(d) for d in self.times]))[0:3]))Athlete類包含三個屬性,其中name屬性是必須提供的,dob和times是缺省的。
完整代碼如下:
class Athlete:# 構造方法,至少要提供一個name值def __init__(self, a_name, a_dob=None, a_times=[]):self.name = a_nameself.dob = a_dobself.times = a_times# 獲取最快的三次記錄def top3(self):return (str(sorted(set([sanitize(d) for d in self.times]))[0:3]))# 格式化字符串 def sanitize(time_string):if('-' in time_string):splitter = '-'elif(':' in time_string):splitter = ':'else:return (time_string)(mins, secs) = time_string.split(splitter)return (mins + '.' + secs)# 從文件讀取訓練數據 def get_coach_data(filename):try:with open(filename) as myfile:# 把讀到的數據按','分隔成一個列表data = myfile.readline().strip().split(',')# 返回一個Athlete對象return (Athlete(data.pop(0), data.pop(0), data))except IOError as ioerr:# 文件異常print('File Error: ' + str(ioerr))return (None)james = get_coach_data('james2.txt') print(james.name + "`s faster times are : " + james.top3())julie = get_coach_data('julie2.txt') print(julie.name + "`s faster times are : " + julie.top3())mikey = get_coach_data('mikey2.txt') print(mikey.name + "`s faster times are : " + mikey.top3())sarah = get_coach_data('sarah2.txt') print(sarah.name + "`s faster times are : " + sarah.top3())? ? 運行結果如圖:
????對于運動員來說,每次訓練完都會有新的數據產生,如果要想把新的數據添加進去,就需要寫新的方法來做這件事(Python中屬性是私有的,外部不可直接訪問修改,而方法是公有的,所以可以通過方法來修改數據)。
? ? 面對這種情況,我們介紹第三種處理數據的方法:繼承內置類
? ? 其實,到我們封裝成類之后,Athlete的times還是用list來存儲的,既然是對times的修改,那么我們能不能繼承list呢?這樣就可以使用list的方法,append,extend等。
類繼承:
class AthleteList(list):def __init__(self, a_name, a_dob=None, a_times=[]):list.__init__([])self.name = a_nameself.dob = a_dobself.extend(a_times)# 獲取最快的三次記錄def top3(self):return (str(sorted(set([sanitize(d) for d in self]))[0:3]))????AthleteList繼承自list,比list多了兩個屬性name和dob,而訓練數據直接用AthleteList自身(從list那繼承過來的屬性)來存儲。
完整代碼:
class AthleteList(list):def __init__(self, a_name, a_dob=None, a_times=[]):list.__init__([])self.name = a_nameself.dob = a_dobself.extend(a_times)# 獲取最快的三次記錄def top3(self):return (str(sorted(set([sanitize(d) for d in self]))[0:3]))# 格式化字符串 def sanitize(time_string):if('-' in time_string):splitter = '-'elif(':' in time_string):splitter = ':'else:return (time_string)(mins, secs) = time_string.split(splitter)return (mins + '.' + secs)# 從文件讀取訓練數據 def get_coach_data(filename):try:with open(filename) as myfile:# 把讀到的數據按','分隔成一個列表data = myfile.readline().strip().split(',')# 返回一個Athlete對象return (AthleteList(data.pop(0), data.pop(0), data))except IOError as ioerr:# 文件異常print('File Error: ' + str(ioerr))return (None)james = get_coach_data('james2.txt') james.append('2.00') print(james.name + "`s faster times are : " + james.top3())julie = get_coach_data('julie2.txt') julie.extend(['2-13', '2:18']) print(julie.name + "`s faster times are : " + julie.top3())mikey = get_coach_data('mikey2.txt') print(mikey.name + "`s faster times are : " + mikey.top3())sarah = get_coach_data('sarah2.txt') print(sarah.name + "`s faster times are : " + sarah.top3())代碼中還順便測了下從list哪兒繼承過來的方法append和extend。
運行結果如圖:
BULLET POINTS:
- 使用dict()工廠函數或{}可以創建一個空字典
- 要訪問一個名為person的字典中與鍵Name關聯的值,可以使用我們熟悉的中括號記法:person['Name']
- 類似于列表和集合,Python的字典會隨著新數據增加到這個數據結構中而動態擴大。
- 可以創建一個空字典然后增加數據,也可以一次完成操作。
- 可以用class關鍵字定義一個類。
- 類方法(代碼)與函數的定義基本相同,也就是說,要用def定義。
- 類屬性(數據)就像是對象實例中的變量。
- 可以類中定__init__()方法來初始化對象實例。
- 類中定義的每個方法都必須有self,從而將數據于其實例相關聯。
總結
以上是生活随笔為你收集整理的《Head First Python》第六章--定制数据对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Boot2.x 整合qua
- 下一篇: 银行大数据风控平台的建设要点与应用