类与封装(Class and Encapsulation) in Python
admin
2023-07-30 20:44:31
0

1 Why Class

(这篇文章是一篇新手级的文章,请高手绕道)
最初人们编程的时候都是用过程在编程。然而随着使用的深入,人们开始使用类。大概的进化过程是这样:

过程—> 过程+函数 —> 类 —> 类&子类……

我们作为一个初学者的时候,往往不明白为什么要用类,为什么不直接用过程就好了。Well, 简短的程序是可以用过程+函数,然而一旦要涉及到很多调用的情况,还是要有Class,让整个程序都可以看起来很清爽。

2 Class is an abstract of things

下面举一个例子:
Al在它的书里面第八章[https://automatetheboringstuff.com/chapter8/] 讲了一个project(Project: Generating Random Quiz Files),就是讲的一个有一个地理老师,他管理了一个35人的班级,准备给他们出一套试题,考考美国的50个州和每个州的首府;由于有很多童鞋喜欢抄袭,所以这个老师就准备每个学生准备一份(美国老师好敬业啊,遥想读书当年,我们的老师最多就提过AB卷),然而如果人工来准备太麻烦了,所以老师决定自动化。

要解决的思路很简单,就是通过几个循环,将答案shuffle开就是,这里写一段伪代码讲讲大致思路:

for 童鞋 = 1 to 童鞋总数(35):
    随机打乱50题

for 每一题 = 1 to 题目总数(50):

             生成正确的答案+错误的答案

             打印问题到试卷文件中

             打印答案到答案文件中

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

新的问题

那么现在问题来了,如果是有一个中国的地理老师是你的朋友,准备跟国际接轨,考中国的34个省的省会,而班上有60位同学,你也准备每人准备一套试卷,要怎么准备呢?

有一个简单的方法就是改参数,然而,这样的问题是,可能而且程序也会显得很ad-hoc。如果又是另一个国家的又怎么办。如果这个地理老师下次再找到你,让你帮忙给班上58位同学准备有48道题的试卷呢?

3 Class Solution

所以这里提出类的方法。听过类的童鞋都知道类有『封装,继承,多态』三个属性。咱们这里会用到封装。
这里是将Al的方法改为Class之后的结果:

# -- 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()

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

封装

你可能会说,这个看着比原来更复杂啊,然而,假如这个是拿给地理老师,他并不需要懂上面那一段,他只需要看懂下面这段代码就是了:

# -- 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\'内蒙古\': 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\'浙江\': 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()

是不是要清爽很多?但为什么这么短呢?因为你把题目封装了,封装将详细的方法隐藏了,所以Class只需要被调用就是;具体的实现,只需要操作一个很小的文件就是了。

继承、多态

可能有同学会说:『我用过程去改一下输入输出也可以做这件事哦』。嘿嘿,好像是可以;然而假如你面对的不是一个地理老师呢?如果是还有其他老师,选择题的选项不止4个怎么办?又拿原来做好的过程文件去改;还是用Class中拉一个subclass出来呢?很明显答案是subclass更好。首先可以继承原来的Class,然后还可以在这个Class上做改变。整个程序也会更清晰。

4 Conclusion

所以咯,学习Class,有一个方法就是把自己原来写的那些过程改一下,这样可以更好的体验哟

上一篇:Flask快速入门

下一篇:Epoll 模型简介

相关内容

热门资讯

500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
Prometheus+Graf... 一,Prometheus概述 1,什么是Prometheus?Prometheus是最初在Sound...
python绘图库Matplo... 本文简单介绍了Python绘图库Matplotlib的安装,简介如下: matplotlib是pyt...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...