類與封裝(Class and Encapsulation) in Python

1 Why Class

(這篇文章是一篇新手級的文章啃匿,請高手繞道)
最初人們編程的時候都是用過程在編程露筒。然而隨著使用的深入断部,人們開始使用類仿粹。大概的進(jìn)化過程是這樣:

過程—> 過程+函數(shù) —> 類 —> 類&子類......

我們作為一個初學(xué)者的時候,往往不明白為什么要用類崭添,為什么不直接用過程就好了寓娩。Well, 簡短的程序是可以用過程+函數(shù),然而一旦要涉及到很多調(diào)用的情況,還是要有Class棘伴,讓整個程序都可以看起來很清爽寞埠。

2 Class is an abstract of things

下面舉一個例子:
Al在它的書里面第八章[https://automatetheboringstuff.com/chapter8/] 講了一個project(Project: Generating Random Quiz Files),就是講的一個有一個地理老師焊夸,他管理了一個35人的班級仁连,準(zhǔn)備給他們出一套試題,考考美國的50個州和每個州的首府阱穗;由于有很多童鞋喜歡抄襲饭冬,所以這個老師就準(zhǔn)備每個學(xué)生準(zhǔn)備一份(美國老師好敬業(yè)啊,遙想讀書當(dāng)年揪阶,我們的老師最多就提過AB卷)昌抠,然而如果人工來準(zhǔn)備太麻煩了,所以老師決定自動化遣钳。

要解決的思路很簡單扰魂,就是通過幾個循環(huán)麦乞,將答案shuffle開就是蕴茴,這里寫一段偽代碼講講大致思路:

for 童鞋 = 1 to 童鞋總數(shù)(35):
    隨機(jī)打亂50題
        
for 每一題 = 1 to 題目總數(shù)(50):
    
             生成正確的答案+錯誤的答案
    
             打印問題到試卷文件中
    
             打印答案到答案文件中

具體思路請看Al的帖子[https://automatetheboringstuff.com/chapter8/] ,搜索Generating Random Quiz Files姐直。

新的問題

那么現(xiàn)在問題來了倦淀,如果是有一個中國的地理老師是你的朋友,準(zhǔn)備跟國際接軌声畏,考中國的34個省的省會撞叽,而班上有60位同學(xué),你也準(zhǔn)備每人準(zhǔn)備一套試卷插龄,要怎么準(zhǔn)備呢愿棋?

有一個簡單的方法就是改參數(shù),然而均牢,這樣的問題是糠雨,可能而且程序也會顯得很ad-hoc。如果又是另一個國家的又怎么辦徘跪。如果這個地理老師下次再找到你甘邀,讓你幫忙給班上58位同學(xué)準(zhǔn)備有48道題的試卷呢?

3 Class Solution

所以這里提出類的方法垮庐。聽過類的童鞋都知道類有『封裝松邪,繼承,多態(tài)』三個屬性哨查。咱們這里會用到封裝逗抑。
這里是將Al的方法改為Class之后的結(jié)果:

# -- coding: utf-8 --# RandomQuizGenerator.pyimport randomcapitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau', 'Arizona': 'Phoenix',            'Arkansas': 'Little Rock', 'California': 'Sacramento',            'Colorado': 'Denver', 'Connecticut': 'Hartford', 'Delaware': 'Dover',            'Florida': 'Tallahassee', 'Georgia': 'Atlanta', 'Hawaii': 'Honolulu',            'Idaho': 'Boise', 'Illinois': 'Springfield', 'Indiana': 'Indianapolis',            'Iowa': 'Des Moines', 'Kansas': 'Topeka', 'Kentucky': 'Frankfort',            'Louisiana': 'Baton Rouge', 'Maine': 'Augusta', 'Maryland': 'Annapolis',            'Massachusetts': 'Boston', 'Michigan': 'Lansing', 'Minnesota': 'Saint Paul',            'Mississippi': 'Jackson', 'Missouri': 'Jefferson City', 'Montana':                'Helena', 'Nebraska': 'Lincoln', 'Nevada': 'Carson City', 'New Hampshire':                'Concord', 'New Jersey': 'Trenton', 'New Mexico': 'Santa Fe', 'New York':                'Albany', 'North Carolina': 'Raleigh', 'North Dakota': 'Bismarck', 'Ohio':                'Columbus', 'Oklahoma': 'Oklahoma City', 'Oregon': 'Salem', 'Pennsylvania':                'Harrisburg', 'Rhode Island': 'Providence', 'South Carolina': 'Columbia',            'South Dakota': 'Pierre', 'Tennessee': 'Nashville', 'Texas': 'Austin',            'Utah': 'Salt Lake City', 'Vermont': 'Montpelier', 'Virginia': 'Richmond',            'Washington': 'Olympia', 'West Virginia': 'Charleston',            'Wisconsin': 'Madison', 'Wyoming': 'Cheyenne'}NUM_OF_STUDENTS = 35NUM_OF_QUESTIONS = 50class RandomQuizGenerator():    def __init__(self, capitals, number_of_students, number_of_questions):        self.capitals = capitals        self.number_of_students = number_of_students        self.number_of_questions = number_of_questions        self.quiz_file = None        self.quiz_answer_file = None    def run(self):        # TODO create a loop of number_of_students quizzes        for quiz_num in range(self.number_of_students):            # Create the quiz and answer key files.            self.init_quiz_file(quiz_num)            # Generate random questions' order for each quiz.            unique_states_list = list(self.capitals.keys())            random.shuffle(unique_states_list)            # loop through all 50 States, making a question for each.            self.generate_one_quiz(unique_states_list)            # Close the quiz_file and the quiz_answer_file            self.close_quiz_file()    def init_quiz_file(self, quiz_num):        self.quiz_file = open('capitalsQuiz%s.txt' % (quiz_num + 1), 'w')        self.quiz_answer_file = open('capitalsQuiz_Answers%s.txt' % (quiz_num + 1), 'w')        # Write out the header for the quiz.        self.quiz_file.write('Name:\n\nDate:\n\nPeriod:\n\n')        self.quiz_file.write((' ' * 20) + 'States Capitals Quiz (Form %s)'                             % (quiz_num + 1))        self.quiz_file.write('\n\n')    def close_quiz_file(self):        self.quiz_file.close()        self.quiz_answer_file.close()    def generate_one_quiz(self, unique_states_list):        for question_num in range(self.number_of_questions):            # Generate wrong answers            question_state = unique_states_list[question_num]            correct_answer = self.capitals[question_state]            wrong_answers = list(self.capitals.values())            del wrong_answers[wrong_answers.index(correct_answer)]            wrong_answers = random.sample(wrong_answers, 3)            # Get the right answer and mingle with the wrong one            answer_options = wrong_answers + [correct_answer]            random.shuffle(answer_options)            # Write the answer to the self.quiz_file            self.quiz_file.write('%s. What is the capital of %s?\n'                                 % (question_num + 1, question_state.encode('utf-8')))            for i in range(4):                self.quiz_file.write(' %s. %s\n' % ('ABCD'[i], answer_options[i].encode('utf-8')))            self.quiz_file.write('\n')            # Write the answer to the self.quiz_answer_file            self.quiz_answer_file.write('%s. %s\n' % (question_num + 1,                                                      'ABCD'[answer_options.index(correct_answer)]))    def change_save_file_name(self, quiz_save_name, answer_save_name):        # TODO The teacher can change the name of the save file.        passdef main():    random_quiz_generator = RandomQuizGenerator(capitals, NUM_OF_STUDENTS, NUM_OF_QUESTIONS)    random_quiz_generator.run()    passif __name__ == '__main__':    main()

¥¥¥¥¥¥¥¥¥¥¥我是文件的分界線¥¥¥¥¥¥¥¥¥¥

封裝

你可能會說,這個看著比原來更復(fù)雜啊,然而邮府,假如這個是拿給地理老師浙于,他并不需要懂上面那一段,他只需要看懂下面這段代碼就是了:

# -- coding: utf-8 --
# china_provincial_capital.py
import RandomQuizGenerator

capitals = {u'北京': u'北京', u'上海': u'上海', u'天津': u'天津', u'重慶':u'重慶', u'新疆': u'烏魯木齊',
            u'黑龍江': u'哈爾濱', u'吉林': u'長春', u'遼寧': u'沈陽', u'內(nèi)蒙古': u'呼和浩特', u'河北': u'石家莊',
            u'甘肅': u'蘭州', u'青海': u'西寧', u'陜西': u'西安', u'寧夏': u'銀川', u'河南': u'鄭州',
            u'山東': u'濟(jì)南', u'山西': u'太原', u'安徽': u'合肥', u'湖北': u'武漢', u'湖南': u'長沙',
            u'江蘇': u'南京', u'四川': u'成都', u'貴州': u'貴陽', u'云南': u'昆明', u'廣西': u'南寧',
            u'西藏': u'拉薩', u'浙江': u'杭州', u'江西': u'南昌', u'廣東': u'廣州', u'福建': u'福州',
            u'臺灣': u'臺北', u'海南': u'盒矗口', u'香港': u'香港', u'澳門': u'澳門'
}


if __name__ == '__main__':
    total_question = len(capitals)
    total_students = 6
    china_capital_quiz = RandomQuizGenerator.RandomQuizGenerator(capitals, total_students, total_question)
    china_capital_quiz.run()

是不是要清爽很多羞酗?但為什么這么短呢?因為你把題目封裝了紊服,封裝將詳細(xì)的方法隱藏了檀轨,所以Class只需要被調(diào)用就是;具體的實現(xiàn)欺嗤,只需要操作一個很小的文件就是了参萄。

繼承、多態(tài)

可能有同學(xué)會說:『我用過程去改一下輸入輸出也可以做這件事哦』煎饼。嘿嘿讹挎,好像是可以;然而假如你面對的不是一個地理老師呢吆玖?如果是還有其他老師筒溃,選擇題的選項不止4個怎么辦?又拿原來做好的過程文件去改沾乘;還是用Class中拉一個subclass出來呢怜奖?很明顯答案是subclass更好。首先可以繼承原來的Class翅阵,然后還可以在這個Class上做改變歪玲。整個程序也會更清晰。

4 Conclusion

所以咯掷匠,學(xué)習(xí)Class滥崩,有一個方法就是把自己原來寫的那些過程改一下,這樣可以更好的體驗喲

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末讹语,一起剝皮案震驚了整個濱河市钙皮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌募强,老刑警劉巖株灸,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異擎值,居然都是意外死亡慌烧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門鸠儿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屹蚊,“玉大人厕氨,你說我怎么就攤上這事⌒谠粒” “怎么了命斧?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嘱兼。 經(jīng)常有香客問我国葬,道長,這世上最難降的妖魔是什么芹壕? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任汇四,我火速辦了婚禮,結(jié)果婚禮上踢涌,老公的妹妹穿的比我還像新娘通孽。我一直安慰自己,他們只是感情好睁壁,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布背苦。 她就那樣靜靜地躺著,像睡著了一般潘明。 火紅的嫁衣襯著肌膚如雪行剂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天钉疫,我揣著相機(jī)與錄音硼讽,去河邊找鬼。 笑死牲阁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的壤躲。 我是一名探鬼主播城菊,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼碉克!你這毒婦竟也來了凌唬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤漏麦,失蹤者是張志新(化名)和其女友劉穎客税,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撕贞,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡更耻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了捏膨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秧均。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡食侮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出目胡,到底是詐尸還是另有隱情锯七,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布誉己,位于F島的核電站眉尸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏巨双。R本人自食惡果不足惜效五,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望炉峰。 院中可真熱鬧畏妖,春花似錦、人聲如沸疼阔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婆廊。三九已至迅细,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淘邻,已是汗流浹背茵典。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留宾舅,地道東北人统阿。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像筹我,于是被迫代替她去往敵國和親扶平。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,094評論 25 707
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法蔬蕊,類相關(guān)的語法结澄,內(nèi)部類的語法,繼承相關(guān)的語法岸夯,異常的語法麻献,線程的語...
    子非魚_t_閱讀 31,625評論 18 399
  • 每一個生命個體的存在,都不會是孤立的猜扮、獨立的勉吻。因為每一個生命都是宇宙的孩子,既然存活在這個空間破镰,就會需要有接...
    是你的六公子閱讀 1,900評論 0 1
  • 1.學(xué)了近10年英語,為什么還是不會說源譬? 從我們那個年代開始集惋,初一就開始學(xué)英語了。初中三年踩娘,高中三年刮刑,大學(xué)四年,1...
    正零閱讀 888評論 6 25
  • 明明很困翘紊,還繃著神經(jīng)硬撐著,不想入眠藐唠。
    小四四四姑娘閱讀 203評論 0 0