《Head First Python》第六章--定制数据对象
先上數(shù)據(jù)集:Head First Python 數(shù)據(jù)集
第六章的數(shù)據(jù)在第五章的基礎(chǔ)上加了兩個(gè)屬性:姓名和出生日期
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????上一章的思路依然沒有問題,還是按照逗號拆分成列表,不過需要多出兩個(gè)變量來保存姓名和出生日期。如果對每個(gè)運(yùn)動(dòng)員都創(chuàng)建兩個(gè)變量,四個(gè)運(yùn)動(dòng)員就是8個(gè)變量,10個(gè)運(yùn)動(dòng)員就得20個(gè)變量,這并不合理。而且這些數(shù)據(jù)之間是有聯(lián)系的,它們都跟同一個(gè)人相關(guān),列表也無法體現(xiàn)這種關(guān)聯(lián)性。
? ? 方法一:數(shù)據(jù)字典
? ? 首先我們采用Python內(nèi)置的一種數(shù)據(jù)結(jié)構(gòu):字典,字典將鍵與數(shù)據(jù)相關(guān)聯(lián),可以使內(nèi)存中的數(shù)據(jù)和實(shí)際數(shù)據(jù)的結(jié)構(gòu)保持一致。
? ? 創(chuàng)建字典的兩種方式:
????????一、james = {}
????? ? 二、james = dict()
? ? james['name'] = 'James Lee'? ?這就是字典中的一個(gè)鍵值對
下面是本章的第一種數(shù)據(jù)處理方法:
# 格式化字符串 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)# 從文件讀取訓(xùn)練數(shù)據(jù) def get_coach_data(filename):# 創(chuàng)建一個(gè)字典接受返回值mydic = {}try:with open(filename) as myfile:# 把讀到的數(shù)據(jù)按','分隔成一個(gè)列表data = myfile.readline().strip().split(',')# 取前兩個(gè)數(shù)據(jù)(pop(0)刪除并返回最前面的數(shù)據(jù)項(xiàng))mydic['name'] = data.pop(0)mydic['DOB'] = data.pop(0)# 對后面的數(shù)據(jù)進(jìn)行格式化,并取最小的三個(gè)數(shù)據(jù)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的最好的三次數(shù)據(jù) james = get_coach_data('james2.txt') print(james['name'] + "`s faster times are : " + james['top3'])# 輸出julie的最好的三次數(shù)據(jù) julie = get_coach_data('julie2.txt') print(julie['name'] + "`s faster times are : " + julie['top3'])# 輸出mikey的最好的三次數(shù)據(jù) mikey = get_coach_data('mikey2.txt') print(mikey['name'] + "`s faster times are : " + mikey['top3'])# 輸出sarah的最好的三次數(shù)據(jù) sarah = get_coach_data('sarah2.txt') print(sarah['name'] + "`s faster times are : " + sarah['top3'])運(yùn)行結(jié)果如圖:
方法二:定義一個(gè)類,利用類對象來體現(xiàn)數(shù)據(jù)結(jié)構(gòu)關(guān)系
? ? Python使用class定義類。每個(gè)定義的類都有一個(gè)特殊的方法,名為__init__(),可以通過這個(gè)方法控制如何初始化對象。
? ? 類中的和函數(shù)的定義類似,同樣是使用def來定義。
? ? Python要求每個(gè)方法的第一個(gè)參數(shù)為調(diào)用對象實(shí)例,也就是說每個(gè)方法的第一個(gè)參數(shù)都是self。
這樣我們就可以對運(yùn)動(dòng)員數(shù)據(jù)進(jìn)行封裝:
class Athlete:# 構(gòu)造方法,至少要提供一個(gè)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類包含三個(gè)屬性,其中name屬性是必須提供的,dob和times是缺省的。
完整代碼如下:
class Athlete:# 構(gòu)造方法,至少要提供一個(gè)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)# 從文件讀取訓(xùn)練數(shù)據(jù) def get_coach_data(filename):try:with open(filename) as myfile:# 把讀到的數(shù)據(jù)按','分隔成一個(gè)列表data = myfile.readline().strip().split(',')# 返回一個(gè)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())? ? 運(yùn)行結(jié)果如圖:
????對于運(yùn)動(dòng)員來說,每次訓(xùn)練完都會有新的數(shù)據(jù)產(chǎn)生,如果要想把新的數(shù)據(jù)添加進(jìn)去,就需要寫新的方法來做這件事(Python中屬性是私有的,外部不可直接訪問修改,而方法是公有的,所以可以通過方法來修改數(shù)據(jù))。
? ? 面對這種情況,我們介紹第三種處理數(shù)據(jù)的方法:繼承內(nèi)置類
? ? 其實(shí),到我們封裝成類之后,Athlete的times還是用list來存儲的,既然是對times的修改,那么我們能不能繼承l(wèi)ist呢?這樣就可以使用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多了兩個(gè)屬性name和dob,而訓(xùn)練數(shù)據(jù)直接用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)# 從文件讀取訓(xùn)練數(shù)據(jù) def get_coach_data(filename):try:with open(filename) as myfile:# 把讀到的數(shù)據(jù)按','分隔成一個(gè)列表data = myfile.readline().strip().split(',')# 返回一個(gè)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。
運(yùn)行結(jié)果如圖:
BULLET POINTS:
- 使用dict()工廠函數(shù)或{}可以創(chuàng)建一個(gè)空字典
- 要訪問一個(gè)名為person的字典中與鍵Name關(guān)聯(lián)的值,可以使用我們熟悉的中括號記法:person['Name']
- 類似于列表和集合,Python的字典會隨著新數(shù)據(jù)增加到這個(gè)數(shù)據(jù)結(jié)構(gòu)中而動(dòng)態(tài)擴(kuò)大。
- 可以創(chuàng)建一個(gè)空字典然后增加數(shù)據(jù),也可以一次完成操作。
- 可以用class關(guān)鍵字定義一個(gè)類。
- 類方法(代碼)與函數(shù)的定義基本相同,也就是說,要用def定義。
- 類屬性(數(shù)據(jù))就像是對象實(shí)例中的變量。
- 可以類中定__init__()方法來初始化對象實(shí)例。
- 類中定義的每個(gè)方法都必須有self,從而將數(shù)據(jù)于其實(shí)例相關(guān)聯(lián)。
總結(jié)
以上是生活随笔為你收集整理的《Head First Python》第六章--定制数据对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Boot2.x 整合qua
- 下一篇: 银行大数据风控平台的建设要点与应用