【回眸】技术干货——Python入门基础篇七合一
技术干货——Python入门基础篇七合一
Python记笔记姿势
Python入门的小伙伴五花八门,而且大概率不是计算机专业的小伙伴,作为一种入门简单的语言,怎么学才是最佳姿势呢?
笔者发现了一种较为适合的Python学习方式&笔记方式,分享给大家。笔记分为两种,第一种是“用法查询笔记”:
用法查询笔记
很多知识并不要求自己直接记在脑子里,可以放到【用法查询笔记】中
第二种是深度理解笔记
知道了学习Python中如何做笔记,那就从0开始吧~
用法查询笔记:
知识:打印
print(666)#打印数字不需要加引号等等
#》》666
print('世界,你好')#打印中文需要加''(英文输入法下的单引号)
#》》世界,你好
print("我颠覆了全世界,只为摆正你的倒影")#打印中文用英文输入法下的双引号也可以,表示告诉机器我输入什么,你原封不动的输出
#》》我颠覆了全世界,只为摆正你的倒影
print("You're my love")#如果打印英语的话,最好是使用双引号,为了防止句子中含有缩写,有单引号导致问题
#》》You're my love
print(6+6)#计算机会 直接计算出6+6的结果
#》》12
print("6+6")#计算机认为这是一个字符串,傻瓜式输出即可
#》》6+6
print('''我叫回眸
初次见面
和我一起学习吧!''')#'''在这里可以让它顺利换行
#》》我叫回眸
#》》初次见面
#》》和我一起学习吧!
print('我颠覆了全世界,\n只为摆正你的倒影\n')#这里\n是转义字符,有换行的作用,和'''作用类似
#》》我颠覆了全世界,
#》》只为摆正你的倒影

知识:赋值 name = '回眸1' name = '回眸' print(name)#name相当于一个可以放东西的盒子,盒子里的值以最后一次为准。 #》》回眸
练习:打印永不宕机的经典图
print(''' _ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// 佛祖保佑 永不宕机 永无BUG //
''')
#》》打印出这个图像
Talk is cheap,show me the code.
看知识获得一时的愉悦感比不过代码敲成的成就感,编程技能的提升没有捷径,需要你不断地刻意练习。
照例:用心做优质Python基础笔记,笔者正在奋笔疾书写博客,方便的话,关注、点赞收藏,一键三连,支持一下~
初学者可以下载pycharm做开发工具,考虑到这个是付费版,不过一般都可以在一些常见的软件公众号里面找到破解方法。
另一个初学者友好选择是anaconda(这里面基本上是Python工具大全了,非常的全面),具体可以参考这篇教程【Anaconda安装与使用】
如果你是初学者并且不会安装配置环境的小白,使用在线编译器菜鸟工具,选择Python3即可。 Python3菜鸟工具
现在,我们开始Python基础的第二站:
数据类型&数据转换
用法查询笔记(数据类型&数据转换):
知识:数据类型(字符串) slogan1 = '人生之美醒时现,何必耽梦负韶华。\n'#这里slogan1是变量名,可以是随便的字母或单词,\n是换行的转义字符,可以不加,这里为了好看,我们可以加一下这个换行的转义字符 slogan2 = "Why waste precious time dreaming when waking life is so much better.\n" slogan3 = "**********$%\n" #上述代码是对三个变量进行赋值 print(slogan1+slogan2+slogan3)#在终端打印出3个变量 #》》人生之美醒时现,何必耽梦负韶华。 #》》Why waste precious time dreaming when waking life is so much better. #》》**********$% 上述的3个变量,均为字符串类型的数据,什么是字符串,答案也就跃然纸上啦 我们可以发现,字符串类型必须有【引号】的辅助
知识:数据类型(整数) a = "Being with you is like walking on a very clear morning."#类型:字符串 b = 520#类型:整数 c = "1314"#类型:字符串 print(a) print(b) print(c) #》》Being with you is like walking on a very clear morning. #》》520 #》》1314 注意!这里520和1314别看都输出来了,实际上数据的类型是不一样的哟,这里 的520属于整数型,但是1314由于带着引号,所以是字符串型 这里有一个坑,如果代码是print(520小埋)会发现终端无情地报错,原因是什么呢? 因为这里没有加引号,机器认为应该是整数型,但是520小埋又不完全是整数型,导致机器无法识别,最后导致报错。
知识:数据类型(浮点数)浮点数
计算机里的浮点数,就是我们现实生活中的小数比如说
print(0.008)
#》》0.008
这里有一个坑小伙伴们,进行浮点数运算时最后结果是不准确的,比如说
print(0.55+0.3)
#》》0.8500000000000001
为什么会造成这样一个细小的误差?
原因是浮点数在做运算时,会先将浮点数转换成二进制的数
# 进制转换
0.55(十进制) = 0.1000110011001100110011001100110011001100110011001101(二进制)
0.3(十进制) = 0.0100110011001100110011001100110011001100110011001101(二进制)
这样再相加后的数字会有一些偏差,后面有更详尽的学习!
接着有几个坑,来看看自己有没有掉坑里吧
print('520')
print(520)
print(520.0)
判断三个输出结果的类型
答案是:字符串型整数型浮点型,答对了给自己奖励一朵小红花

上面是Python中关于运算符的介绍 ,运算顺序和数学一样
上面的题目有个鸡贼的方法,就是在编译器上跑一跑,你就知道是什么类型的数据了
a = '520' b = 520 c = 520.0 print(type(a)) print(type(b)) print(type(c)) #》》<class 'str'> #》》<class 'int'> #》》<class 'float'> 电脑帮我们判断数据的类型实在是太赞了 这里科普一下,str是string的缩写,意思是字符串 int是integer的缩写,意思是整数 float不是缩写,意思是浮点数
知识:数据转换 负责转换数据类型的函数一共有3种:str()、 int()和float()。 magic = '水仙花数' action = '是' unit = '个' expression = '=1x1x1+5x5x5+3x3x3' number = 153 print(str(number)+str(expression)+action+unit+magic) #》》153=1x1x1+5x5x5+3x3x3是个水仙花数 注意这里同类型的字符串才能拼接!! 所以把int型的数字强制转换成了字符串型的数字,完成了输出 number1 = '2' number2 = '4' print(int(number1)+int(number2)) #》》6 print(int(3.8)) #》》3 age = '18' print(float(age)) #》》18.0
数据类型和数据转换这一节顺利结束了,下面做一下总结:
用法查询笔记:(条件判断之单向判断)
score = 150
if score == 150:
print("地表最强学术大佬考了满分")
#》》地表最强学术大佬考了满分
上述代码中有个很明显的基础条件判断,if
有什么注意事项呢?
首先,一个= 是赋值符号,是将150赋值给score,后面用if判断score,
用的是== 两个=在Python语句中才是代表等于的意思。
另一个注意点是if后面加上判断条件后要用:(英文输入法下的冒号)结尾
这是初学者容易遗漏的地方。
最后一个注意点是print前面有四个空格或者一个tab键的缩进
注意这里一定要有缩进不然会报错!
Python里面没有缩进,不讲究结构是万万不可的,缩进代表着他们是紧密联系的
报错结果显示为:IndentationError: expected an indented block
条件判断之双向判断
用法查询笔记:(条件判断之双向判断)
score = 89
if score >= 90:
print("幸运仔仔,你及格啦");
else:
print("不巧没及格,下次努力")
#》》不巧没及格,下次努力
这里注意,比起第一个代码块,这个代码块里面增加了else语句
并且大家注意这里else语句不要缩进,else下面的print需要缩进,
这样既不会报错,看起来干净整洁,又遵循了语法规则。
上述代码块用图表形式总结就是下面这张图:
条件判断之多项判断
用法查询笔记:(条件判断之多项判断)
上面的代码块让笔者动了成绩管理demo的心思,接下来要介绍多项条件判断了
score = 145
if 120<score<=150:
print("优秀啊,捕捉到一枚平平无奇的学术小天才")
elif 90<score<=120:
print("可以啊,捕捉到一只合格的祖国花朵")
elif 0<=score<=90:
print("发现九年义务教育漏网之鱼")
else:
print("别开玩笑,输入正确的成绩")
#》》优秀啊,捕捉到一枚平平无奇的学术小天才
差点翻车了,笔者写这个多项判断的时候掉沟里去了,因为C语言也有这些条条框框嘛,笔者把他们搞混了,复习了一下规则啥的,才写顺溜的。
笔者强调一下各位老爷可能的翻车点吧,第一个就是这个大于小于号,很人性化的写法,但是C语言里面可不能这么写,Python语法更偏向于生活中的写法。
另一个点就是缩进和对齐,这几个条件都是并列的,所以elif和if属于同级
最后一个点就是elif可以无限添加,想要几个就要几个吗,但是有禁忌!
elif后面不能直接加else!

看到这里的老爷们 请注意,这个时候建议做两个舒尔特方格专注一下再来学习条件嵌套
用法查询笔记:(条件嵌套)
上述的demo也可以用条件嵌套来完成!
score =146
if score>=90:
print("你已经及格")
if score>120:
print("你是学神")
else:
print("你做的还不错")
else:
print("你还没有及格")
if score>60:
print("还能抢救一下")
else:
print("你是义务教育漏网之鱼,请和我回去改造")
print("程序结束")
#》》 你已经及格
#》》你是学神
#》》程序结束
这个嵌套可能各位老爷们看着会有些纳闷,下面这张图片看起来结构会清晰很多
一共有3个if条件判断,其中有两个小if嵌套在一个大if条件判断里面

用法查询笔记:(input()函数 )
food = input('请在以下四个选项 【啤酒鸭;冰淇淋;奶茶;水果玉米】输入一项你最喜欢的食物:')
print('原来你是喜欢'+ food +'的小可爱')
#>>请在以下四个选项 【啤酒鸭;冰淇淋;奶茶;水果玉米】输入一项你最喜欢的食物:
#>>(在交互界面输入啤酒鸭)
#>>计算机就会回答你啦,他会说
原来你是喜欢啤酒鸭的小可爱
当要求输入的是整数的时候,一定要注意代码里面是不是int型,假如代码里面默认是int型的,一定要记得强制转换成string型
choice = input('你喜欢啤酒鸭吗:1表示喜欢')
#给choice赋值
if choice == str('1'):
#条件判断
print('hin好,啤酒鸭也喜欢你')
#打印出判断结果
else:
print('不嘛,你是不是手抖输错了')
#>>你喜欢啤酒鸭吗:1表示喜欢
#>>这个时候记得输入1
hin好,啤酒鸭也喜欢你
发现了没有,终端输入的类型默认为字符串型
所以如果遇到这种事情,要记得将判断条件强制转换成字符串型。
列表
什么是列表?
随便写一个: class(列表名) = (赋值) ['高一四班','高二八班','高三六班'](外部是中括号,用逗号隔开)。
一个列表需要用中括号[ ]把里面的各种数据框起来,里面的每一个数据叫作“元素”。每个元素之间都要用英文逗号隔开。
这就是列表的标准格式,现在请创建一个列表名为list1的列表,列表里有三个元素:'啤酒鸭',18,1.75,并将其打印出来:
list1=['啤酒鸭',18,1.75] print(list1)
列表很包容,各种类型的数据(整数/浮点数/字符串)无所不能包。
取出列表里具体的某一个元素
但问题来了,如果只想取出列表里具体的某一个元素该怎么办呢?
这就涉及到一个新的知识点:偏移量。列表中的各个元素,好比教室里的某排学生那样,是有序地排列的,也就是说,每个元素都有自己的位置编号(即偏移量)。
从上图可得:1.偏移量是从0开始的,而非从1开始;2.列表名后加带偏移量的中括号,就能取到相应位置的元素。
所以,可以通过偏移量来对列表进行索引(可理解为搜索定位),读取我们所需的元素。
在【‘啤酒鸭’,'DD','回眸','咸蛋超人'】里取出啤酒鸭这个元素的代码是怎么样的呢?
students = ['咸蛋超人','啤酒鸭','DD','回眸'] print(students[1])
从列表提取多个元素
list2 = [5,6,7,8,9] print(list2[:]) print(list2[2:]) print(list2[:2]) print(list2[1:3]) print(list2[2:4])
用冒号来截取列表元素的操作叫作切片,顾名思义,就是将列表的某个片段拿出来处理。这种切片的方式可以从列表中取出多个元素。
冒号左边空,就要从偏移量为0的元素开始取;右边空,就要取到列表的最后一个元素。后半句:冒号左边数字对应的元素要拿,右边的不动。
速记:左右空取到头,左要取,右不取。
students = ['啤酒鸭','回眸','严啤啤','啤雅雅'] print(students[:3])
给列表增加/删除元素
增加元素:
append函数并不生成一个新列表,而是让列表末尾新增一个元素。而且,列表长度可变,理论容量无限,所以支持任意的嵌套。
students = ['小明','小红','小刚']
students.append('小美')
print(students)
使用append 添加元素可以将新元素添加到链表里。
删除元素:
del语句非常方便,可以删除一个元素,也能一次删除多个元素(原理和切片类似,左取右不取)。
语法是:del 列表名[元素的索引]
students = ['小明','小红','小刚','小美'] del students[1:2] print(students)
运行的结果是发现小红删了。
字典
这次期中考呢、,小啤、小眸、小严分别考了95、90和90分。
假如还用列表来装数据的话,需要新创建一个列表来专门放分数,而且要保证和姓名的顺序是一致的,很麻烦。所以类似这种名字和数值(如分数、身高、体重等)两种数据存在一一对应的情况,用第二种数据类型——“字典”(dictionary)来存储会更方便。
students = ['小啤','小眸','小严']
scores = {'小啤':95,'小眸':90,'小严':90}
print(len(scores))
scores(字典名) = {'小啤'(键):95(值),'小眸':90,'小严':90}(大括号)
列表中的元素是自成一体的,而字典的元素是由一个个键值对构成的,用英文冒号连接。如'小啤':95,其中我们把'小啤'叫键(key),95叫值(value)。
这样唯一的键和对应的值形成的组合,我们就叫做【键值对】,上述字典就有3个【键值对】:'小啤':95、'小眸':90、'小严':90
如果不想口算,可以用len()函数来得出一个列表或者字典的长度(元素个数),括号里放列表或字典名称。
这里需要强调的是,字典中的键具备唯一性,而值可重复。
如果你不小心声明了两个以'小啤'为键的【键值对】,后出现的【键值对】会覆盖前面的【键值对】。打印出的值也会以后面一个为准。
这便是从字典中提取对应的值的用法。和列表相似的是要用[ ],不过因为字典没有偏移量,所以在中括号中应该写键的名称,即字典名[字典的键]。
如果想取出小啤的成绩的值,可以运行下面的代码
scores = {'小啤':95,'小眸':90,'小严':90}
print(scores['小啤'])
字典的删改
删除字典里键值对的代码是del语句del 字典名[键],而新增键值对要用到赋值语句字典名[键] = 值。
scores = {'小啤':95,'小眸':90,'小严':90}
del scores['小严']
scores['小严']=92
scores['小菜']=85
print(scores)
列表和字典的异同
差异
列表中的元素是有自己明确的“位置”的,所以即使看似相同的元素,只要在列表所处的位置不同,它们就是两个不同的元素。
而字典相比起来就显得随和很多,调动顺序也不影响。因为列表中的数据是有序排列的,而字典中的数据是随机排列的。
这也是为什么两者数据读取方法会不同的原因:列表有序,要用偏移量定位;字典无序,便通过唯一的键来取值。
共同点
在列表和字典中,如果要修改元素,都可用赋值语句来完成
第二个共同点即支持任意嵌套。除之前学过的数据类型外,列表可嵌套其他列表和字典,字典也可嵌套其他字典和列表。
练手demo
练习目标:
我们会通过今天的作业,更熟练地取出层层嵌套中的数据,并了解一种新的数据类型:元组。
练习要求:
我们知道了列表和字典的不同:列表的基本单位是元素,而字典里是键值对。所以,两者提取数据的方式也不同。
你可以通过头两个练习来验证自己已经掌握了。
而在第三道练习,你会学会提取元组里的数据。
1、请你通过所学知识,把列表list1中的'love'取出来,并打印出来。
2、请你通过所学知识,把字典dict1中的'love'取出来,并打印出来。
3、下面,介绍一种新的数据类型:元组(tuple)。 可以看到:元组和列表很相似,不过,它是用小括号来包的。
元组和列表都是序列,提取的方式也是偏移量,如 tuple1[1]、tuple1[1:]。另外,元组也支持任意的嵌套。
请你根据以上提供的信息,将tuple1中的A和list2中的D打印出来。看到了,理解了,运用了,就能够掌握了。
for...in...循环
for...in...三要素
1.空房间
2.等待循环的内容
3.循环的流程
空房间的名字一般为i,也可以根据实际需要选择其他命名。
等待循环的内容的最后一个值在循环结束后会保留。
注意,等待循环的内容不可以是整数和浮点数,可以是列表、字典、字符串等等。
range(a,b)函数
range(a,b)函数可以留头去尾
用法1:
for i in range(3,9):print('PJY')效果:打印了六遍指定内容
用法2:
for i in range(0,10,3):print(i)
range(a,b,c)
a:计数从a开始,默认为0,可以不填
b:计数从b结束,但是不包括b
c :计数间隔:默认为1,可以不填
While 循环
while循环有2个条件
1.放行条件
2.办事流程
while循环本质上像是一个哨卡:只要事情符合条件,那就一遍又一遍的“按流程办事”
用法1:
i=0while i <100:i=i+1print(i*5)
结果1:
用法2:
a = 0
while a < 5: a = a + 1print(a)
结果2:
for循环和while循环的区别for循环和while循环最大的区别在于【循环的工作量是否确定】,for循环就像空房间依次办理业务,直到把【所有工作做完】才下班。但while循环就像哨卡放行,【满足条件就一直工作】,直到不满足条件就关闭哨卡。
所以说,当【工作量确定】的时候,可以让for循环来完成重复性工作。反之,要【工作量不确定时】可以让while循环来工作。
课后练习
小明、小红、小刚是同班同学,且坐在同一排,分别坐在第一位、第二位、第三位。由于他们的身高都差不多,所以,老师计划让他们三个轮流坐在第一位。每次换座位的时候,第一位变第三位,后面两位都往前一位。
students = ['小明','小红','小刚']for i in range(3):student1 = students.pop(0) # 运用pop()函数,同时完成提取和删除。students.append(student1)# 将移除的student1安排到最后一个座位。print(students)
函数的定义和调用
用法1:
def math(x):y = x ** 2 + xreturn y
a = math(10)print(a)
结果1:
带参数的函数定义和调用
用法1:
def menu(appetizer, course, dessert = '绿豆沙'):
print('一份开胃菜:' + appetizer)
print('一份主食:' + course)
print('一份甜品:' + dessert)
menu('话梅花生','牛肉拉面')
menu('话梅花生','牛肉拉面','银耳羹')
#银耳羹对应参数dessert
结果1:
print函数的完整参数:
print(*objects, sep = ' ', end = '\n', file = sys.stdout, flush = False)
第一个参数objects带了号,为不定长参数——这也是为什么print()函数可以传递任意数量的参数。其余四个为默认参数。
修改 print函数的参数:
print('金枪鱼', '三文鱼', '鲷鱼')
print('金枪鱼', '三文鱼', '鲷鱼', sep = '+')
# sep控制多个值之间的分隔符,默认是空格
print('金枪鱼', '三文鱼', '鲷鱼', sep = '+', end = '=?')
# end控制打印结果的结尾,默认是换行)
结果:
多个返回值:
import random
appetizer = ['话梅花生','拍黄瓜','凉拌三丝']
def coupon(money):
if money < 5:
a = random.choice(appetizer)
return a
elif 5 <= money < 10:
b = random.choice (appetizer)
return b, '溏心蛋'
print(coupon(4))
print(type(coupon(6)))
结果:
global语句申明局部变量为全局变量
rent = 3000
def cost():
global variable_cost
utilities = int(input('请输入本月的水电费用'))
food_cost = int(input('请输入本月的食材费用'))
variable_cost = utilities + food_cost
print('本月的变动成本是' + str(variable_cost))
def sum_cost():
sum = rent + variable_cost
print('本月的总成本是' + str(sum))
cost()
sum_cost()
可以通过global +变量,将变量申明为全局变量。
类与对象
Python中的对象等于类和实例的集合:即类可以看作是对象,实例也可以看作是对象,比如列表list是个类对象,[1,2]是个实例对象,它们都是对象。
类的创建
类中的属性和方法
注意:类名的首字母要大写
创建类:Chinese
类名首字母大写
class Chinese:
# 用赋值语句,创建类的属性
eye = 'black'
# 创建实例方法时,不要漏了 self
def eat(self):
print('吃饭,选择用筷子。')
创建好类之后还需要进行调用
类的调用
实例1:
class Computer:
screen = True
def start(self):
print('电脑正在开机中……')
my_computer = Computer()
print(my_computer.screen)
my_computer.start()
my_computer = Computer()
这个过程叫作:类的实例化,即在某个类下创建一个实例对象。
打印实例类型和直接打印出实例
实例2:
class Computer:
screen = True
def start(self):
print('电脑正在开机中……')
my_computer = Computer()
print(type(my_computer))
print(my_computer)
结果2:
<class 'main.Computer'>验证了my_computer属于Computer这个类
Computer类的一个实例对象,后面的一串字符表示这个对象的内存地址
当实例my_computer一被创建出来,就可以调用类中的属性和方法。一句话概括就是:类有的实例都会有。
调用的语法是实例名.属性和实例名.方法
实例3:
class Computer:
screen = True
def start(self):
print('电脑正在开机中……')
my_computer = Computer()
print(my_computer.screen)
my_computer.start()
结果3:
倒数第二行:my_computer.screen先是获取到类属性screen对应的值True,再用print()打印出来。
最后一行:my_computer.start()调用方法start(),这个方法的功能是直接打印出'电脑正在开机中……'。
参数self的特殊之处:在定义时不能丢,在调用时要忽略。
实例4:创建一个Chinese实例,要求属性——眼睛是黑色,吃饭用筷子
class Chinese:
eyes = 'black'
def eating(self):
print('吃饭选择用筷子')
you =Chinese()
print (you.eyes)
you.eating()
结果4:
类中创建的属性和方法可以被其所有的实例调用,而且,实例的数目在理论上是无限的。我们可以同时“新建”多个实例。
创建类的两个关键点
特殊参数:self
特殊参数self的作用:self会接收实例化过程中传入的数据,当实例对象创建后,实例便会代替 self,在代码中运行。
实例5:
class Chinese:
name = '啤酒鸭'
def say(self):
print(self.name + '是中国人')
person = Chinese()
person.say()
结果5:
实例person会像参数一样传给self,替换掉self,第六行的self.name等价于person.name。
person.name就相当于调用了类属性name(即'啤酒鸭'),然后跑完整个方法。
self的作用相当于先给实例占了个位置,等到实例创建好就“功成身退,退位让贤”。
在类的方法内部调用其他方法时,也需要用到self来代表实例。
第一点:只要在类中用def创建方法时,就必须把第一个参数位置留给 self,并在调用方法时忽略它(不用给self传参)。
第二点:当在类的方法内部想调用类属性或其他方法时,就要采用self.属性名或self.方法名的格式。
特殊方法:初始化方法
定义初始化方法的格式是def init(self),是由init加左右两边的【双】下划线组成( initialize 的缩写)。
初始化方法的作用在于:当每个实例对象创建时,该方法内的代码无须调用就会自动运行。
实例6:
class Chinese:
class Chinese:
def __init__(self):
print('很高兴遇见你,我是初始化方法')
person = Chinese()
结果6:
初始化方法类似于于设置一个初值,这样类中的其他方法就能直接、随时调用。
如果在编程的过程中需要传入的数据能在类中长久保存并能被随时调用,初始化方法就是一个不错的解决方案。
实例7:
class Chinese:
def __init__(self, hometown):
self.hometown = hometown
print('你在哪里出生?')
def born(self):
print('我生在%s。' % self.hometown)
pijiuya = Chinese('上海') # 传给参数hometown
pijiuya.born()
结果7:
面向对象编程
面向对象编程,会将程序看作是一组对象的集合,用这种思维设计代码时,考虑的不是程序具体的执行过程(即先做什么后做什么),而是考虑先创建某个类,在类中设定好属性和方法,即是什么,和能做什么。接着,再以类为模版创建一个实例对象,用这个实例去调用类中定义好的属性和方法即可。
用类编写一个直观的好处就是参数的传递会比普通函数要省事很多,也不必考虑全局变量和局部变量,因为类中的方法可以直接调用属性。
可想而知,当项目难度越大,需要的参数越多,用类编写在程序的可拓展性、可读性、维护成本都会更胜一筹。
面向对象编程和面向过程编程区别
总结一下:面向对象编程实际上也是一种对代码的封装。只不过,类能封装更多的东西,既能包含操作数据的方法,又能包含数据本身。所以,代码的可复用性也更高。而且,对于需要长期更新的代码而言,面向对象编程写成的代码结构会更清晰。所以,代码的可读性、可拓展性和可维护性这几个方面都会优于面向过程编程。这个优势让我们可以在 Python 中轻松地调用各种标准库、第三方库和自定义模块(可以简单理解成别人写好的类),这是Python 之所以这么强大和热门的主要原因之一。这也是为什么我在开头说“面向对象编程,会为你打开一个新的世界”。将他人封装好的代码为自己所用,效率和能做的事情自然是天壤之别。
类的继承
A继承了B类的属性和方法 = A是B的子集。
继承的基础语法
而子类继承的属性和方法,也会传递给子类创建的实例
实例8:
class Chinese:
eye = 'black'
def eat(self):
print('吃饭,选择用筷子。')
class Shanghai(Chinese):
pass # pass表示'跳过',不执行其他操作
pijiuya = Shanghai()
print(pijiuya.eye)
pijiuya.eat()
结果8:
很多类在创建时也不带括号,如class Chinese:。这意味着它们没有父类吗?
实际上,class Chinese:在运行时相当于class Chinese(object):。而object,是所有类的父类,我们将其称为根类(可理解为类的始祖)。
各级实例和各级类之间的关系
在类的继承中,不仅子类属于父类,子类所创建的实例实际上也同时属于父类。
理论上,父类可以被无限个子类所继承(这一点好比类的属性方法可以传递给无限个实例)。
比如说如果要为每个省级行政区的人各创建一个类,并添加各种属性和方法。那么,只要创建一个父类Chinese,在父类中将共同的属性和方法写好,然后34个类都可以通过类的继承得到Chinese的属性和方法,代码量可以减少十几甚至几十倍。
类的继承之多层继承
继承不仅可以发生在两个层级之间(即父类-子类),还可以有父类的父类、父类的父类的父类
实例9:
class Earthman:
eye_number = 2
class Chinese(Earthman):
eye_color = 'black'
class Shanghai(Chinese):
pass
pijiuya = Shanghai()
print(pijiuya.eye_number)
print(pijiuya.eye_color)
结果9:
子类创建的实例可调用所有层级父类的属性和方法。
类的继承之多重继承
越靠近子类(即越靠左)的父类,越亲近,越优先考虑。子类调用属性和方法时,会先在靠左的父类里找,找不到才往右找。
多层继承和多重继承的区别
类的定制
子类也可以在继承的基础上进行个性化的定制,包括:(1)创建新属性、新方法;(2)修改继承到的属性或方法。
简而言之:类的定制,不仅可以让子类拥有新的功能,还能让它有权修改继承到的代码——在写这句话时,我仿佛看到子类化成了一个人,抬头瞟了一眼在他上方的父类,淡淡地说了一句话:以我为主,为我所用。
所以,当我们谈定制时,已经包含了继承。毕竟,类的定制的前提是继承,而定制的加入让类的继承不仅仅只是单纯的复制而已。这也是我们创建子类的意义。
定制,可以新增代码
在子类下新建属性或方法,让子类可以用上父类所没有的属性或方法。这种操作,属于定制中的一种:新增代码。
实例10:
class Chinese:
eye = 'black'
def eat(self):
print('吃饭,选择用筷子。')
class Shanghai(Chinese): # 类的继承
native_place = 'Shanghai' # 类的定制
def dialect(self): # 类的定制
print('我们爱吃甜。')
pijiuya = Shanghai()
print(pijiuya.eye)
# 父类的属性能用
print(pijiuya.native_place)
# 子类的定制属性也能用
pijiuya.eat()
# 父类的方法能用
pijiuya.dialect()
# 子类的定制方法也能用
结果10:
定制,也可重写代码
子类继承父类方法的操作是在def语句后接父类.方法(参数),如上述代码的第八、九行。
这样一来,父类方法land_area中的说法改变,子类也不用去动,因为子类直接继承了父类的方法。只不过,在继承的基础上,通过参数的调整完成了定制。
而参数的调整,可以增加参数(如 rate),也可以改变参数的默认值
实例11:
class Chinese:
def land_area(self,area):
print('我们居住的地方,陆地面积是%d万平方公里左右。' % area)
class Cantonese(Chinese):
# 为参数 area 设置默认值。
def land_area(self, area = 960, rate = 0.0188):
Chinese.land_area(self, area * rate)
yewen = Cantonese()
yewen.land_area()
结果11:
练习要求:
练习会先提供一个类,用以记录学生学习 Python 的投入时间和有效时间。
需要你创建一个子类,为某一类学生提供定制化的记录方案。
练习目标:
这个练习,主要是训练你对“子类的继承”的理解和运用。
练习要求:
练习会先提供一个类,用以记录学生学习 Python 的投入时间和有效时间。
需要你创建一个子类,为某一类学生提供定制化的记录方案。
用代码记录时间
class Student:
def __init__(self, name, job=None, time=0.00, time_effective=0.00):
self.name = name
self.job = job
self.time = time
self.time_effective = time_effective
def count_time(self, hour, rate):
self.time += hour
self.time_effective = hour * rate
# 请你完成子类的定制(包括初始化方法和count_time函数)
class Programmer(Student):
# 通过两个实例,完成子类和父类的对比(可自行验证)
student1 = Student('韩梅梅')
student2 = Programmer('李雷')
通过类的定制升级代码
假设:编程开发人员学 Python 的话,学习效率很高,默认为1。
而且,job 的属性为 programmer。
请你补全上面的代码,将其升级。
后记
类的继承和定制,从某个角度来看,和人类的科技史很像:每一代人,都“继承”了上一代的科技,同时“定制”属于这一代的科技。于是,科技的发展越来越先进。今天所享受到科技的便利和乐趣,来源于一代又一代的人在科技上的传承和创新。
#实习必须要去大厂吗?##我的秋招日记##秋招有哪些公司要求提前实习#本专栏助应届生从物联网小白成长为企业争抢的技术人才,聚焦三大核心技术:传感器应用(环境监测)、嵌入式开发(STM32/Arduino)、通信协议(LoRa/NB-IoT/MQTT),配合10+实战项目(如智能温湿度监控系统)积累项目经验。覆盖智能硬件、工业物联网、智能家居领域岗位需求,解析企业招聘技术重点与面试题,帮电子、计算机、自动化等专业学生构建知识体系,提前锁定名企Offer!
