#0-4关 0-4关相对比较简单,所以助教会讲得快一点哦~
#第0关 print函数 print()函数由两部分构成:1. 指令:print;2. 指令的执行对象:在print后面的括号里的内容。 我们对电脑下指令——把括号里的内容打印给我瞧瞧
*单引号,双引号、三引号 1)单引号‘ ‘和双引号“ “:直接输出 2)三引号‘‘’ ‘’‘:换行 *转义字符 “换行”的转义字符是\n *变量命名规范: 2、变量的命名规范 1.只能用一个词 2.只能包含字母、下划线和数字 3.不能以数字开头 4.尽量描包含的内容 转义符号: 1、\n(换行) 例子:print('把我的幻影和梦\n放在狭长的贝壳里\n柳枝编成的船篷\n还旋绕着夏蝉的长鸣\n拉紧桅绳\n风吹起晨雾的帆\n我开航了') 以下是拓展:(只做了解,不用掌握使用方法)
#第1关 #第1关:主要内容是数据类型和数据拼接 数据类型分为;int,str,float 数据拼接需要数据类型一致 需要注意的是:input默认输出为字符串,在后面与int做条件判断的时候,需要先转换数据类型为int(input());同时数字做数据拼接时,需要使用str(number) #第2关 第2关:主要内容是单向判断,双向判断,多项判断 单向判断为:if 双方判断为:if……else 多项判断为:if……elif ……elif……else 需要注意的是: if……if……if与if……elif……elif的区别,执行的模块数量,if……if,是不管前一个测试是否通过 条件的判断: and 和 or的使用, and,表示且,满足a且满足b条件,则为True,进入下一步; or,表示或,表示满足a或者满足b,则为True,进入下一步: 这里有些同学有不恰当使用and的栗子哟~ 比如: #知识点:条件and和or x=input('请给小狗起个名字:') if x == '小狗' and x =='汪汪': #正确应为if x == '小狗' or x =='汪汪': #or表示两个条件满足一个,就执行下一步 #and表示两个条件同时满足,才进行下一步 #第3关 #第三关的重点是input函数,也就是输入。 1)a=input(),把输入的值给变量; 2)input是输入,print是打印,两个是不一样的哟。 举个栗子🌰 teacher=input('我最喜欢的助教是:') print('我最喜欢的助教是:'+teacher) #这次山顶被问到的一个问题是:a=print(2),则a为None,因为print函数不返回值。 这里是前四关,比较简单,所以过的比较快,这里有需要提问的同学嚒 #第4关 #列表 #列表:[],元素,包容多种数据类型,有序((一般英文表示为list) #列表切片,使用‘’符号 list2 = [5,6,7,8,9] print(list2[:]) #输出结果为[5,6,7,8,9],冒号:表示取全部 print(list2[2:]) #这里是从偏移量为2的算起(左取),所以对应输出的为[7,8,9],冒号:表示取后面所有 print(list2[:2]) #这里是到偏移量为2(右不取),所以对应输出为[5,6],冒号:表示取前面所有 print(list2[1:3]) #这里对应的为偏移量1(左取)到偏移量为3(右不取),所以输出对应为[6,7] print(list2[2:4]) #这里对应的为偏移量2(左取)到偏移量为4(右不取),所以输出对应为[7,8] #增加或删除元素 #增加元素,使用append函数,格式是列表名.append( ): a = [1,2,3] b = [4,5,6] b.append(a) print(b) #输出结果为:[4, 5, 6, [1, 2, 3]],将列表作为一个元素添加 注意区别于extend()函数 d = [4,5,6] c= [1,2,3] d.extend(c) print(d) #输出结果为:[4, 5, 6, 1, 2, 3] #删除元素, 方法一:使用del函数,格式是del 列表名[元素的索引]),可删除任何位置的列表元素 a=[5,6,7,8] del a[3] print(a) 方法二:使用pop函数,将元素从列表删除,并接着使用他的值 a=[5,6,7,8] a1=a.pop(3) print(a1) 拓展1:元组 Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。(一般英文表示为tuple) 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。 tup1 = ('physics', 'chemistry', 1997, 2000) tup2 = (1, 2, 3, 4, 5, 6, 7 ) 元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例: tup1 = (12, 34.56) tup2 = ('abc', 'xyz') tup3 = tup1 + tup2 print(tup3) #则打印结果为(12, 34.56, 'abc', 'xyz') 列表相关函数 sort和sorted函数排序:区别在于sort为永久性,sorted为临时性 详情请查看链接:https://blog.csdn.net/guoyang768/article/details/84428171 其他列表常用函数还有:https://www.cnblogs.com/yi-xixi/p/10973686.html (这里仅做了解不要求掌握) #字典 #字典:数据存在一一对应情况;{};键具备唯一性,而值可重复 #新增键值对要用到赋值语句字典名[键] = 值 dic={'七七':180,'Billy':190} dic['班助']=220 print(dic) #打印结果为{'七七': 180, 'Billy': 190, '班助': 220} #字典删除元素 dic={'卡西':180,'Lin':190} del dic['Lin'] print(dic) #输出:{'卡西': 180} #字典增加元素 dic={'七七':180,'Billy':190} dic['班助']=220 print(dic) #打印结果为{'七七': 180, 'Billy': 190, '班助': 220} #方法items()方法:字典里面提取key和value(键和值)的方法 A={'绿色':1,'红色':2,'黄色':3} for key,value in A.items(): #print(key) #输出绿色,红色,黄色 print(value) #输出1,2,3 #字典使用keys(方法):字典提取键 A={'绿色':1,'红色':2,'黄色':3} for key in A.keys(): #print(key) #输出绿色,红色,黄色 #字典使用values方法:字典提取值 A={'绿色':1,'红色':2,'黄色':3} for value in A.values(): print(value) #输出1,2,3
items()函数的用法:https://blog.csdn.net/u011475210/article/details/77770145 #习题讲解 list1 = [{'嫉妒':'envy'},{'恨':'hatred'},{'爱':'love'}] print(list1[2]['爱'])
# 第一步:取出列表中的第三个元素(list1[2]),字典{'爱':'love'}; # 第二步:取出list1[2]中键'爱'所对应的值,即'love’(list1[2]['爱'])。
dict1 = {1:['cake','scone','puff'],2:['London','Bristol','Bath'],3:['love','hatred','envy']} print(dict1[3][0])
# 第一步:取出字典中键为3对应的值(dict1[3]),即['love','hatred','envy']。 # 第二步:再取出列表['love','hatred','envy']中的第一个元素(dict1[3][0])。
tuple1 = ('A','B') list2 = [('A','B'),('C','D'),('E','F')]
print(tuple1[0]) print(list2[1][1])
# 从代码里,也可看出:1.元组内数据的提取也是用偏移量;2.元组也支持互相嵌套。 townee = [ {'海底王国':['小美人鱼''海之王''小美人鱼的祖母''五位姐姐'],'上层世界':['王子','邻国公主']}, '丑小鸭','坚定的锡兵','睡美人','青蛙王子', [{'主角':'小红帽','配角1':'外婆','配角2':'猎人'},{'反面角色':'狼'}] ] print(townee[5][1]['反面角色']) #不清楚的时候,我们可以用print去尝试 #首先townee是一个列表,最外面的[]得知 #其次为列表内嵌套了字典和列表,我们分层应该为: townee = [ {'海底王国':['小美人鱼''海之王''小美人鱼的祖母''五位姐姐'],'上层世界':['王子','邻国公主']}, #偏移量为0 '丑小鸭', #偏移量为1 '坚定的锡兵', #偏移量为2 '睡美人', #偏移量为3 '青蛙王子', #偏移量为4 [{'主角':'小红帽','配角1':'外婆','配角2':'猎人'},{'反面角色':'狼'}] #偏移量为5 ] #print(townee[5]),输出结果为[{'主角':'小红帽','配角1':'外婆','配角2':'猎人'},{'反面角色':'狼'}] #分层为: [{'主角':'小红帽','配角1':'外婆','配角2':'猎人'},#偏移量为0 {'反面角色':'狼'}] #偏移量为1 #print(townee[5][1]),输出结果为{'反面角色':'狼'} #最后就是字典的提取值的方法啦 #第5关 #for和while循环 #循环:把一件事执行很多遍 #一般由两种语句,1)for...in...循环语句;2)另一种是while循环语句 #for循环
常见用法如下: #1.1)for in循环与列表 for i in [1,2]: print(i) #遍历列表,所以这里的i为依次遍历的元素哟
#1.2)for in循环与字典 dict = {'日本':'东京','英国':'伦敦','法国':'巴黎'}
for i in dict: print(i) #遍历字典,这里的i为字典的键 print(dict[i]) #dict[i]为字典的值的提取方式,所以这里打印为的字典的值
#1.3)for i循环与字符串 #注意这里不可以为浮点或整数 for i in '吴承恩': print(i)
#2.for和range函数搭配 # 使用range(x)函数,就可以生成一个从0到x-1的整数序列,类似[a,b) #for i in range(0,10,3):,生成从1,10,间隔为3的序列 for i in range(0,10,3) print(i) #所以这里的i输出为0,3,6,9 #while循环 一般格式为 n=某个值 while 条件: 执行语句
#习题讲解 方法一: man = '' # 注:''代表空字符串,作用是个变量定义 while man != '有': #注:!=代表不等于 #也就是空字符不等于有,所以满足条件,进入循环,开始input输入 man = input('有没有愿意为小龙女死的男人?没有的话就不能出古墓。') print('小龙女可以出古墓门下山啦~')
#方法二: man = '没有' # 注:''代表空字符串 while man == '没有': #注:!=代表不等于 #进入循环,需要满足条件,所以最开始的定义,给了'没有' #满足条件进入循环 man = input('有没有愿意为小龙女死的男人?没有的话就不能出古墓。') print('小龙女可以出古墓门下山啦~') password = '' # 变量password用来保存输入的密码 while password != '816': password = input('请尝试输入密码:') #因为password赋值为input时,input默认输出为字符串类型,所以上面条件需要加引号 print('欢迎回家!') 当我们【工作量确定】的时候,我们就可以让for循环来完成重复性工作。 反之,要【工作量不确定时】可以让while循环来工作。
#课后习题 #方法一:使用for循环和pop函数 students = ['小明','小红','小刚'] for i in range(3): student1 = students.pop(0) # 运用pop()函数,将偏移量为0的元素赋值给变量student1,也就是,把第一个座位的同学提取出来。同时更新了列表 students.append(student1) # append函数,将元素添加到列表尾,将移除的student1安排到最后一个座位。 print(students) #打印列表 #方法二:使用while循环和pop函数 students = ['小明','小红','小刚'] i=0 while i<3: i=i+1 student1 = students.pop(0) # 运用pop()函数,同时完成提取和删除。 students.append(student1) # 将移除的student1安排到最后一个座位。 print(students) #方法三:for循环和切片 students = ['小明','小红','小刚'] for i in range(3): student1 = students[0] students = students[1:] students.append(student1) print(students) #方法四:while循环和切片 students = ['小明','小红','小刚'] i=0 while i<3: i=i+1 student1 = students[0] students = students[1:] students.append(student1) print(students) #第6关 布尔值和四种语句 #第6关的主要内容为:布尔值和四种语句 #布尔值:True和False(一般条件为True则继续循环,条件为False则结束循环) 布尔值的其他情况
#四种语句 break语句,用法如下
i = 0 #给i赋值,定义变量 while i<5: #循环条件,当满足i小于5时,持续循环 print('明日复明日') #满足条件则进行下一步 i = i+1 #更新i的值,以便打破循环条件 if i==3: # 当i等于3的时候触发 break # 结束循环 continue语句:当某个条件被满足的时候,触发continue语句,将跳过之后的代码,直接回到循环的开始。用法如下:
pass语句:跳过,不执行任何语句 else不但可以和if配合使用,它还能跟for循环和while循环配合使用
#习题讲解 n = 0 #list_answer = {} list=[] #定义空列表 while True: n += 1 a = input('A,你认罪吗?请回答认罪或者不认:') b = input('B,你认罪吗?请回答认罪或者不认:') #list_answer[n]=[a,b] #字典增加键和键值的方法 list.append([a,b]) #列表增加元素的方法 if a == '认罪' and b == '认罪': #对囚犯的选择进行判断,打印对应的刑罚 print('两人都得判10年,唉') elif a == '不认' and b == '认罪': print('A判20年,B判1年,唉') elif a == '认罪' and b == '不认': print('A判1年,B判20年') else: print('都判3年,太棒了') break #print(list_answer) #print('第' + str(n) + '对实验者选了最优解。') for i in range(n): #for i in range(n),是取出0到n-1的序列 print('第' + str(i+1) + '对实验者的选择是:' + str(list[i])) #这里的list_answer[i]根据偏移量提取列表元素,i是for i in range(n)中i的取值 #print('第' + str(i+1) + '对实验者的最优选择是:' + str(list[i])) #因为囚徒困境(博弈论知识),的最优选择为【不认,不认】,所以输出列表的最后一次选择就可以 主要思路: 1)设置空列表,用于存储值 2)因为有不确定次数的囚犯回答,所以我们利用while循环 3)input输入囚犯回答,if……elif用于判断 4)打印结果
#第7关 总体思路: #1.1展示随机属性&随机生命值和攻击值 #1.2展示PK过程 #1.3展示每一局的PK结果,并设置三局两胜,也就是在每一局外面设置for i in range(1,4)的循环 #1.4展示三局两胜的最后PK结果,借助第三方变量,类似篮球积分 #1.5设置三局两胜在输入某个键时,是否继续循环,也就是while True部分 #随机展示敌我双方角色,生命值和攻击值(需要注意导入模块和定义变量)
#展示攻击过程
#开始判断敌我双方的胜利 #将一局判断循环3遍,达到三局两胜的情况,同时引入变量,开始积分(类似篮球赛)
引入player_victory记录分数,如果我方胜利,则+1分;如果敌方胜利,则我们-1分;否则平局不扣分,通过最后的分值是否为正,统计PK结果 #是否继续游戏
新的“格式化字符串”的方法:format()函数 # % 格式化:str % () print('%s%d'%('数字:',0)) print('%d,%d'%(0,1)) print('%d,%d,%d'%(0,1,0))
name1 = 'Python' print('I am learning %s'% name1) # 注:当只跟一个数据时,%后可不加括号,format()一定要有。 # format()格式化函数:str.format() print('\n{}{}'.format('数字:',0)) # 优势1:不用担心用错类型码。 print('{},{}'.format(0,1)) # 不设置指定位置时,默认按顺序对应。 print('{1},{0}'.format(7,8)) # 优势2:当设置指定位置时,按指定的对应。 print('{0},{1},{0}'.format(5,6)) # 优势3:可多次调用format后的数据。
name2 = 'Python基础语法' print('我正在学{}'.format(name2)) # format()函数也接受通过参数传入数据。 #第8关 第8关我们主要是了解一个学习方法
这里同学们要自己好好应用这些方法,去做好笔记。好记性不如烂笔头,自己梳理笔记,学习效果更好哦! 第9关 第9关我们学习了函数 什么是函数呢?
下面来讲讲怎样定义和调用函数 定义和调用函数 首先我们要定义函数,怎么定义函数呢?
比如: def 助教(名字): print(名字+'很棒哟!') return
第1行:def的意思是定义(define),greet是【函数名】(自己取的),再搭配一个括号和冒号,括号里面的name是参数(参数名也是自己取)。 第2行:def下一行开始缩进的代码是函数要实现的功能,也叫【函数体】。这里的函数体展现出的功能就是:打印出“name+ 早上好”这句话。 第3行:一个简单的return。函数内部一旦遇到return语句,就会停止执行并返回结果。没有return语句的函数,Python也会在末尾隐性地加上return None,即返回None值(return None可以简写为return。)
!!!定义函数只是将函数的内部功能封装起来(组织好),运行不会输出任何内容!!! 定义完函数之后,还需要调用才会执行函数内的语句~下面来讲讲怎么调用函数! 调用函数 怎么调用函数呢?在Python里,就是输入函数名和参数对应的值: def 助教(name): print('我最喜爱的助教是'+name) 助教('卡西') #调用函数,输入函数名助教()并输入参数'卡西' 助教('七七') #调用函数,输入函数名助教()并输入参数'七七' 助教('延君') #调用函数,输入函数名助教()并输入参数'延君' 调用函数最关键的是:得弄清楚这个函数有多少个参数,如何给参数赋值,这个过程在函数里叫做参数的传递(传参)。 有多少个参数(没有默认值)就要传多少个参数的值进去。 接下来讲一下函数的一些概念:参数、变量、return 函数重要概念 参数类型 主要的参数类型有:位置参数、默认参数、不定长参数。 【位置参数、默认参数】
参数可以替换! 【不定长参数】 不限定死数量,这时候【不定长参数】就能派上用场,即不确定传递参数的数量。 它的格式比较特殊,是一个星号*加上参数名
!!!默认参数也需要放在不定长参数的后面,即dessert=’绿豆沙'要放在*barbeque后面,否则传递的值会对应不上!!!
1、加了一个星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。 如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。 ('烤鸡翅', '烤茄子', '烤玉米'),这种数据类型叫做元组(tuple) 元组的写法是把数据放在小括号()中,它的用法和列表用法类似,主要区别在于列表中的元素可以随时修改,但元组中的元素不可更改。 2、加了两个星号 ** 的参数会以字典的形式导入。 详情可以点击链接了解:https://blog.csdn.net/weixin_38280090/article/details/85623286 return语句
如:
#最终输出是“嗯,人生才刚刚开始” main()函数内部分别调用了face()和body()函数,参数dream_face和dream_body传递给了face()和body()函数的参数name,得到返回值,并打印。
前面所有的return语句,都是返回1个值。 Python语言中的函数返回值可以是多个,而其他语言都不行,这是Python相比其他语言的简便和灵活之处。一次接受多个返回值的数据类型就是元组。
而元组与列表其实都是数据的“序列”,元组取某个位置的值的操作,与列表偏移量是一模一样的,即tuple[]
再来讲一下变量 变量作用域 第一点:在一个函数内定义的变量仅能在函数内部使用(局部作用域),它们被称作【局部变量】。 第二点:在所有函数之外赋值的变量,可以在程序的任何位置使用(全局作用域),它们叫【全局变量】。
!!!全局作用域中的代码中也不能使用任何局部变量!!! 建议局部变量和全局变量【不要】取相同的名字,以免混淆。 当变量在函数内时,就是局部变量,只能在这个函数内被访问; 当变量在函数外时,就是全局变量,可以在程序中的任何位置被访问 全局作用域中的代码中也不能使用任何局部变量。
也可以用global语句将变量声明为全局变量!!!【用global声明了全局变量,就可以在局部里面修改这个变量的值】
#课后练习 定义两个函数:第一个函数功能为根据工作月数返回奖金额,第二个函数功能为打印出'该员工来了XX个月,获得奖金XXX元'。 发放奖金的要求如下: 工作时长不满六个月,发放固定奖金500元。 工作时长在六个月和一年之间(含一年),发放奖金120元*月数(如8个月为960元) 工作时长在一年以上,发放奖金180元*月数 (如20个月为3600元) def bonus(month): if month < 6: money = 500 return money elif 6 <= month <= 12: money = 120 * month return money else: money = 180 * month return money
def info(name, month): gain = bonus(month) print('%s来了%s个月,获得奖金%s元' % (name, month, gain))
info('大聪',14) 好啦,山脚阶段课程的知识点的梳理就讲到这里,同学们有哪里还不明白的吗?可以先在群里讨论哈~下午继续复习山腰、山顶阶段的知识~
首先,因为山腰课程有两个实操,分别是10、14关。这两关的实操因为涉及的知识点不太多,助教不做知识点的讲解,到后面有疑问的集中答疑 # 我们直接从11关的知识开始 第11关知识讲解 # 11关的课程目标是学会debug的方法以及如何避免bug # 在我们运行程序时,如果遇到报错,会有三个关键信息 # 1)line x代表这个bug出现在第x行,在Debug的时候,可以优先从第x行开始检查; # 2)^代表bug发生的位置 # 3)错误类型,如SyntaxError指的是语法错误。对英文不熟悉的直接复制查百度。 # 当我们遇到程序报错的时候,我们可以根据自检清单来进行排查 #
# 这个常见报错类型同学们一定要看看:https:///docs/eyTFT6cZL68IhU6z/ 《那些年我们遇到的报错》,可复制链接后用石墨文档 App 或小程序打开 # 因为同学们经常会在打代码的时候,犯粗心的错误,粗心是同学们最常见的第一种报错类型 # 所以在敲代码的时候就要细心一点啦,像缺符号特别是少一个括号,缩进,没有定义变量这种错误~都是可以避免的 # 第二种,就是知识不熟练 # 这个需要同学们多去复习知识点,熟悉具体的使用方法 # 第三种,思路不清 # 遇到代码多的时候,不知道到底哪里出错了 # 这种情况,可以在关键步骤print出来,看是否达到我们所期望的结果,以此来揪出错误的那一步 # 或者使用#号把后面的代码注释掉,一步一步运行,可以帮助排除错误 #
# 第四种,被动掉坑 # 指有时候你的代码逻辑上并没有错,但可能因为用户的错误操作或者是一些“例外情况”而导致程序崩溃。例如: #
# 在这个程序中,当输入的不是纯数字时,会报错ValueError:invalid literal for int() with base 10 : # 因为,int()函数不能接受非数字的字符串。 # 像这种情况,我们可以用到try...except语句 #
#
#
# try...except语句可以用三种用法,这个应该不难理解 详细的用法可以参考这个链接:https://blog.csdn.net/chenmozhe22/article/details/82850001 # 11关的知识点不难,主要是希望同学们能学会自己根据报错信息去找错误 # 养成自己debug的习惯 # 尤其到了山顶的课程,更需要自己依靠自己去找解决方法 # 这也是学习编程过程中很关键的技能 第12、13关知识讲解 # 12关、13关我们学习的面向对象编程,是山腰学习中最重要的知识内容 # 学习这两关的目标是 # 1)了解何为对象 2)区分变量与类属性,函数与类方法 3)掌握类的实例化及初始化函数 4)熟练继承与子类定制 # 涉及到的难点有: 类的实例化,初始化函数的改写,继承的用法 # 首先我们要知道,什么是面向对象编程 # 面向对象编程就是以对象为中心,将一组对象组成程序。使用于较复杂,尤其需要持续更新的代码场景。 # 比如甲乙丙丁都做一道西红柿炒蕃茄的菜(做的味道都不一样),这个做菜的程序就是面向过程。 # 甲写了一份西红柿炒蕃茄的菜谱,乙丙丁按照这个菜谱步骤做出味道一样的西红柿炒蕃茄(不管谁按这个菜谱来做,都是一样味道),这个程序叫做面向对象。 # 相信同学们在学习中也能感受到,使用类的调用是很方便的一件事情 # 那么类是什么? # 类,是一个函数包。类中可以放置函数和变量,然后类中的函数可以很方便的使用类中的变量,(也就是类方法可以调用类属性) # 类中的 函数 叫 方法,类中的 变量 叫 属性 # 这个需要搞清楚哦 # 创建类的时候,类名首字母要大写 # 且后面不要忘记冒号“:” #
#
# 那么,方法和属性我们知道了,那什么是参数呢? # 参数是,我们在定义函数的时候,需要传递给类方法的东西 # 我们举个例子 #
# 在这里的代码中,我们在定义函数的时候,留了一个需要手动传递参数的位置 # 所以在调用类方法的时候,需要手动设置一个参数 # 如果没有设置参数,或者参数设置多了,都会报错 # 但有一种情况可以不手动设置参数 # 那就是在定义方法的时候,将需要的参数设置为默认参数 #
# 在同一个类里面,不同方法之间,还可以实现方法的调用 # 举个栗子 #
# 在方法 live()中,就调用了方法 born() # 这边也举一个实例调用类方法的例子 #
# 左边是错误,右边是正确的例子 # 左边的错误在于 1:在类方法下调用其他方法的时候,先进行了实例 2:调用类方法的格式错误 # 顺着这个例子,我们接着讲到,类的实例化是什么?实例怎么使用? # 类是对象的模板,可以复制出多个对象,这个过程叫实例化 # 格式 : 实例名=类名() #
# 这里要注意,类实例化的时候,类的括号不能丢 # 被创造出来的实例与类一模一样,但是它是独立的对象 # 调用类属性和类方法的格式分别为: 调用类的属性:实例名.属性; 调用类的方法:实例名.方法() # 这里给大家展示一下例子 #
# 这个例子属于,在类外部调用类的属性 # 我们用print语句将my_computer这个实例的screen这个属性打印出来 # 属性可以在外部调用,也可以在类的内部调用 # 当在类的方法的内部想调用类的属性或类的其他方法时,就要采用self.属性名或self.方法名的格式。(相当于改变了作用域) #
# 有同学问,为什么实例调用方法时不用传参,定义时不是有个参数self吗? # 这就是参数self的特殊之处:在定义时不能丢,在调用时要忽略(就是占位的作用) # self的作用是,self会接收实例化过程中传入的数据,当实例对象创建后,实例便会代替 self,在代码中运行 # 通俗一点理解,只要记住,加上self.前缀的类属性和类方法,准确来说叫实例属性和实例方法,可以在类下的不同类方法中实现调用 # 那么,实例的对象,和类之间有什么联系呢 # 首先,实例属性和类属性: 1)修改类属性,这会导致所有实例属性变化(因为类是模板); 2)修改实例属性,但这不会影响到其他实例,也不会影响到类。因为每个实例都是独立的个体。 #
# 其次,实例方法和类方法: 1)重写类方法,这会导致所有实例方法自动被重写; 2)实例方法不可重写 #
# 再跟大家讲一下,如何修改类方法 # 上面也说了,类方法可重写,实例方法不可重写 # “重写类方法”分成两个步骤: 1)在类的外部写一个函数, 2)把这个新函数的名字赋值给 类.原始函数: #
# 注意:这里的赋值是在替换方法,并不是调用函数,所以【不要加上括号】 # 初始化函数 # 初始化函数(方法),也叫构造函数,它的意思是,当你创建一个实例的时候,这个函数就会被调用(自动执行)。 # 初始化函数的写法是固定的格式:中间是“init”,这个单词的中文意思是“初始化”,然后前后都要有【两个下划线】,然后__init__()的括号中,第一个参数一定要写上self,不然会报错 # 也就是写成def __init__(self): #
# 我们一般会用初始化函数来做什么呢? # 在初始化方法内部完成类属性的创建,为类属性设置初始值,这样类中的其他方法就能直接、随时调用。不需要再调用__init__() # 举个栗子 #
# 在这个类中,一旦调用,就会自动执行初始化函数创建类属性 # 在初始化函数的定义时,也可以设置需要传递的参数位置 # 在实例化类的时候,可直接手动传入参数 #
# 继续讲最后一个知识,类的继承 # 类的继承很大程度也是为了避免重复性劳动。比如说当我们要写一个新的类,如果新的类有许多代码都和旧类相同,又有一部分不同的时候,就可以用“继承”的方式避免重复写代码; # 同理,在类的继承后,子类重写初始化函数时调用父类的初始化函数,也是因为许多代码都和旧类相同,又有一部分不同的时候,就可以用调用的方式避免重复写代码; # 子类创建的实例,同时属于父类 父类创建的实例,不属于子类; #
# 这个例子属于类的定制和调用,能够理解这个代码,其实对于类的继承最核心的知识就掌握了 # 上面提到,子类重写初始化函数,其实在子类中,可以重新任何方法 # 但我们还是以重新初始化函数为例子 #
# 在这个代码中,Knight类继承了Role类 # 并重新初始化函数,修改了类属性 # 这里可以改为另一种写法,也就是重写子类初始化函数时,调用父类的初始化函数。或者可以理解为父类方法的继承 #
继续举栗子 #
# 先看这个,没有继承的类方法调用 #
# 这个子类继承后,修改了方法,再进行调用 #
# 同学们在自己敲代码的时候,遇到不知道变量到底有没有被修改这些情况的时候 # 就可以通过print去打印看看 # 这个过程中也有助于自己熟悉打代码的感觉,熟悉句式的使用 # 多练,多练 下面给大家讲解一下10、12、13关课后习题哈,给你们巩固一遍知识 第10关课后习题讲解 ### 我们第十关的练习是和电脑进行剪刀石头布 ### 这里会用到的知识点有: 1. random模块的使用 2. while循环实现输入判断 3. if条件语句进行条件判断输出结果 在进阶练习中还会涉及到一个新知识: 4. index()函数的使用 ### 1.random模块大家应该不陌生,我们在山脚第七关的实操课中也有学习过 不过之前学习到的是random.randint()的使用,这次我们要用到的是random.choice() random.choice()是random模块中有个随机选取一个元素的方法,我们在练习的使用上,是从列表punches = ['石头','剪刀','布']随机选取一个元素,作为电脑的出拳选择 ### 2. while循环实现输入判断 while user_choice not in punches: # 当用户输入错误,提示错误,重新输入 print('输入有误,请重新出拳') user_choice = input() while user_choice not in punches 意思是当user_choice不在列表punches中时,进行循环 在循环下,给user_choice重新赋值~再进行循环,直至输入正确 ### 3. if条件语句进行条件判断输出结果 这一部分应该不难理解,就是列出可能会出现的各种出拳组合,根据不同的组合情况进行结果的输出
但是我们能看出,这样的方法虽然很直观,也能达到目的,但是不够高级,不够简洁 所以在进阶练习中,我们学习到一个新知识index() 函数 ### 4.index() 函数用于找出列表中某个元素第一次出现的索引位置 语法为:list.index(obj),obj为object(对象)的缩写。 简单的看一下这个例子,了解用法
在课程上,可能大家都比较难理解注释里所讲的索引减1是什么意思
这里我们可以结合这张图解一起来看 当电脑出拳为布,索引为2,若玩家想赢,则需出拳为剪刀,索引为1 punches.index(computer_choice)-1 则是将电脑的索引减1,才与玩家的索引相等 当电脑出拳为石头,索引为0,若玩家想赢,则需出拳为布,索引为2 这里就需要注意了,布的索引从正数为2,从倒数则是-1 所以石头的索引0-1=-1,也就是布的索引 第12关课后习题讲解 ### 第12关的课程练习是对课程的一个拓展,其实难度不大,也没有太多同学反馈有不理解的问题。所以助教也会把整个逻辑简单的讲一遍 ### 课程要求是:新建一个方法,让实例只要调用一个方法,就能打印出两个信息。 这里我们会用到初始化函数,还有在函数内调用类属性 ### 我们先来看直接调用类的实现方式
这里我们定义了一个类,类下包含一个初始化函数,两个普通方法 在初始化函数中,我们会给它传递两个参数,并将这两个参数赋值给self.hometown和self.region 这里有同学的疑问是,为什么要把参数重新赋值呢?为什么不可以直接使用? 因为hometown和region作为参数的时候,是只在该方法下有效的,而其他方法不能直接调用这个参数 如果想调用,就要用到重新赋值给一个变量,且这个变量需带有self.的前缀,这样才能实现在不同的类方法下调用该变量(也叫属性)
所以我们看到在后面的两个方法中,分别对两个属性进行了调用 看上图的代码,最后的调用中,只调用了Chinese()这个类,这样的运行结果,其实没有实现题目的要求 因为单单调用Chinese类的时候,只会执行初始化函数,而不会再进行其他的操作 ### 既然题目说了,要新建一个方法,且只调用一个方法,就能打印出两个信息。那么我们就需要用一个main()来把打印两个信息的方法再封装起来 完整代码如下
在这里的main()方法下,按顺序调用 self.born()和 self.live()两个方法 所以当我们在最后调用的时候,只需要调用main()就可以同时执行另外的两个方法了,运行结果就是根据调用时手动传递的参数打印出两个语句 ### 助教再讲一下第二个练习吧,简单讲一下,其实跟第一个练习相似,只不过在某个方法中还加入了一个循环,但是逻辑上理解是一样的
这道题助教从函数执行的顺序开始讲 首先执行 robot1 = Robot() 进行实例化,实例化的同时也执行了函数的初始化函数
看我把最后一句注释掉,只执行robot1 = Robot() 的时候,只执行初始化函数的部分 当我把最后一句加上时,实例robot1调用方法say_wish()
在say_wish()下,先用input输入并赋值给wish 这里有同学问,为什么这里的wish不用加self.哇? 是因为wish这个变量,它只在该方法下进行使用,你看它不需要在其他类方法被调用,对吧。所以是可以不加self.的 所以最后通过一个循环,打印三遍,完成题目要求 第13关课后习题讲解 ### 来简单的讲一下13关的习题吧,13关我们学到的主要知识就是 【类的继承】 考虑到同学们对继承逻辑的理解会稍微比较绕,所以13关的习题也设置得比较简单,目的也是让同学们以最直观的方式进行继承的操作 而稍微复杂的操作,我们会在14关的实操课中去学习 来看习题,第一个目标和要求
这个题目在练习中已经给出了代码,但是同学们也要理解
首先这里Teacher类和Father类个字有两个属性,其中一个同名属性face 我们用time1 和 time2分别对两个类进行实例化,再调用各自的face属性
记得在创建实例的时候,格式是 实例名 = 类() 括号不能丢 然后用 实例名.属性 的方式调用了类的属性,并用print进行打印 第二部分,课程要求是
代码如下
### 我们先定义了 class TeacherMore(Teacher, Father): pass 这里按照多重继承的逻辑,会优先继承Teacher这个父类,在这个类下,pass的意思是完全继承,不做修改 ### 再者,我们定义了 class FatherMore(Father, Teacher): face = 'gentle' 这里按照多重继承的逻辑,会优先继承Father这个父类,在这个类下,对属性face进行了重新赋值,修改为‘gentle’ 我们用time3 和 time4分别对两个子类进行实例化,再调用各自的face属性 time3是子类TeacherMore()的实例,因为没有重新赋值face,所以优先继承了Teacher这个父类的face属性,打印为serious time4是子类FatherMore()的实例,因为重新赋值了face,所以此时打印重新赋值后的face属性,打印为gentle ### 助教继续讲第二个进阶练习
先看初级版本,在类下两个方法,一个初始化方法,一个普通方法 初始化的作用是一般会用来执行一些默认的操作,比如把参数赋值,这样当调用类的时候,则默认执行初始化函数,不用手动进行调用 而普通方法则是实现特定功能的调用,这里的count_time()则用来计算效率 同学会问,为什么在init里,要重新对参数赋值呢,self.的作用是什么 这里对参数重新赋值到一个变量,目的是为了在其他的类方法进行调用,只有加了self.前缀的才能进行调用哦 如果没有加self. , 则只能在该方法下使用
看第一个实例,调用了类Student,并传入了一个参数给name 在init中,因为其他的参数都是默认参数,所以调用的时候只传参给name即可
第二步,实例student1调用类方法count_time()并传入两个参数,并打印属性self.time_effective,具体逻辑如上图
在实例调用某个属性的时候,格式是 实例名.属性名,此时不用加self. ### 接下来是升级版
子类Programmer()继承了父类Student(),并进行了类方法的重写(定制)
子类重写初始化函数,修改了原参数中job的默认值,并在在函数下调用了父类的初始化函数,参数传递如上图
子类重写count_time方法,修改了原参数中rate的默认值,参数传递如上图
创建实例student1和student2,参数传递如上图
实例student1和student2分别调用count_time()方法,参数传递如上图
15关知识点 编码: 什么是编码? 计算机本来是一个只认识0和1的计算机,为了更好的交流,这种从人类语言到计算机语言转换的形式,叫做编码表。数字或者字母在计算机储存的时候需要转换成二进制,每个人转换的规则就叫做编码。 人类语言 → 计算机语言 encode() 计算机语言 → 人类语言 decode() 二进制: 通俗来讲就是0和1,因为计算机只认识这两个,所以通过不同的排列来表示相关的状态,不需要纠结太多,那是计算机的问题,我们通常有编码表转换成人类语言,如果非要关心二进制,跟10进制转化,可以善用百度上面有现成的转换计算器,非科班出身的我们懂得这回事就可以啦`
文件读写: python代码调用电脑文件的主要功能。 文件读取: 牢记步骤:打开文件 —— 读取文件 —— 关闭文件 模板写法:
第二行代码是把读取到的内容存到了filecontent变量里面,下面打印出来,read()函数通常是整个读取出来,但是不同情况时候我们需要按行读取,也就是一行行,这里要利用到readlines()函数其他都不会变,替换read()函数就可以 切记用open函数最后要close()文件 写入文件:
同样要记住最后要close() 不过如果加一个with关键字,比如withopen那么写完之后自己就会关闭,不需要close() 当然写入的数据多种多样,我们要更换写入或者读取的模式,记住下面这个表很关键!!!
其他知识点: split()函数: 按照空格分割字符串,str.split() join()函数: 把字符串合并,用法是str.join(sequence),str代表在这些字符串之中,你要用什么字符串连接,在这里两个例子,一个是空字符串,一个是横杠,sequence代表数据序列,在这里是列表a writelines() 因为write()的参数必须是一个字符串,但是有时候我们要写入别的内容,所以用到writelines()这后面的参数可以是列表 16关:模块的调用(明白底层原理,学会使用即可) 模块: 什么是模块? 最高级别程序组织单元,通常我们调用的模块都是写好的py文件,里面有各种变量,函数,类 等可执行的语句 调用模块: import 语句: 1、最常见的,import 模块名 例: import random random.randint ;(代码里面调用模块里面方法的格式,模块名.方法名,这里面randint是模块里面写好的方法,我们学会调用就ok,明白方法的功能) 2、import 模块名 as 简写: 例: import random as ra ra.randint;后面就可以利用ra代表random 3、导入多个模块: 例: import a,b,c ;(表示同时导入a,b,c三个模块) 4、从模块中只导入一个指定部分: from...import.... 例:
5、判断文件是不是被当成模块调用,来执行相关语句: if_name_== '__main__'
自学模块: 如果英文好的同学,可以直接阅读官方文档:https://docs./3.6/library/random.html 或者也可以直接百度搜索。 csv模块: 简易版excel,也是表格文件。csv模块的用法:
17关邮件 写在前面: 这一关重在应用,因为涉及到跟邮箱服务器连接问题,所以这里之后的代码要懂得,无法实现效果不一定是代码问题,比如还有可能邮箱服务器关闭了你的连接端口,很有可能同一段你写的代码别人可以发送成功,你这里就失败。 不要纠结,不要难过,这个锅甩给邮箱公司 这里我们学会利用代码实现固定功能,重要的是模板的套用! 成功发送的同学也不要开心起来就发个没玩,更加不要写循环发送,这样不止会导致封掉端口,还会给邮箱服务器带来很多没必要的负载~ 我们尝试过理解应用就好,大家都是善良的人,要做有爱的事! # smtplib 用于邮件的发信动作 import smtplib from email.mime.text import MIMEText # email 用于构建邮件内容 # 发信方的信息:发信邮箱,QQ 邮箱授权码 from_addr = 'xxx@qq.com' password = '你的授权码数字' # 收信方邮箱 to_addr = 'xxx@qq.com' # 发信服务器 smtp_server = 'smtp.qq.com' # 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码 msg = MIMEText('send by python','plain','utf-8') # 开启发信服务,这里使用的是加密传输 server = smtplib.SMTP_SSL(smtp_server) server.connect(smtp_server,465) # 登录发信邮箱 server.login(from_addr, password) # 发送邮件 server.sendmail(from_addr, to_addr, msg.as_string()) # 关闭服务器 server.quit() 本关卡具体实操项目: 重点说一些易错点: 1、
缺少host参数,这里要加上smtp_server也就是上面代表的'smtp.qq.com' 2、
授权码问题,要自己邮箱开启pop3服务,记住授权码不要加空格 3、
端口问题,qq邮箱的话建议试用465, 465频率比较高,或者25 多换一下这个是默认的 4、
报错无法解码,可能是python文件执行路径存在中文命名,彻底修改或者新建电脑用户(重新搭建python本地环境,比较麻烦) 第18关 一、流程图 顺序结构: 三种图形(带方向的线段,椭圆形,长方形) 解释: 带方向的线段-将流程图中的图形元素连接起来表示流转方向,可在线上添加备注文字 椭圆形-流程图的开始和结束 长方形-流程图中的主要表达的元素,表示一个动作(业务动作、功能动作等) 条件结构: 四种图形(带方向的线段,椭圆形,长方形,菱形 解释: 带方向的线段-将流程图中的图形元素连接起来表示流转方向,可在线上添加备注文字 椭圆形-流程图的开始和结束 长方形-流程图中的主要表达的元素,表示一个动作(业务动作、功能动作等) 菱形:表示逻辑判断,一般会连接Yes或No,两条分支流程 循环结构: 四种图形(带方向的线段,椭圆形,长方形,菱形) 解释: 带方向的线段-将流程图中的图形元素连接起来表示流转方向,可在线上添加备注文字 椭圆形-流程图的开始和结束 长方形-流程图中的主要表达的元素,表示一个动作(业务动作、功能动作等) 菱形:表示逻辑判断,一般会连接Yes或No,两条分支流程 ***循环有两种情况,一种是条件判断后进行循环(菱形),一种是结束某个流程后进入循环(长方形) 第19关 项目解示 代码一: import csv #调用csv模块 with open('assets.csv', 'a', newline='') as csvfile: #调用open()函数打开csv文件,传入参数:文件名“assets.csv”、追加模式“a”、newline=''。 writer = csv.writer(csvfile, dialect='excel') # 用csv.writer()函数创建一个writer对象。 header=['小区名称', '地址', '建筑年份', '楼栋', '单元', '户室', '朝向', '面积'] writer.writerow(header) #用writerow()函数将表头写进csv文件里 (1)newline='',是为了解决写入时CSV文档出现的空行 (2)dialect='excel',是默认的编码格式 (3)如果你用的是Mac电脑,当你直接用excel打开csv文件可能会显示乱码; 解决方法:在open()函数里加上参数'encoding='GBK' 代码二: start_floor = input('请输入起始楼层:') #end_floor = input('请输入终止楼层:') #确定每一单元有几层楼 start_floor_rooms = {} #创建字典,存放起始楼层所有户室的信息 floor_last_number = [] #创建列表,存放户室的尾号如['01','02','03'],后续楼层可复用
last_number = input('请输入起始楼层户室的尾号:(如01,02)')
floor_last_number.append(last_number) #将元素添加到存放户室尾号的列表里,如floor_last_number = ['01'] room_number = int(start_floor + last_number) #户室名为room_number,由楼层start_floor和尾号last_number组成,如'301' direction = int(input('请输入 %d 的朝向(南北朝向输入1,东西朝向输入2):' % room_number )) #输入中文比输入数字要麻烦许多,我们可以先用1和2代替 area = int(input('请输入 %d 的面积,单位 ㎡ :' % room_number)) start_floor_rooms[room_number] = [direction,area] # 户室号为键,朝向和面积组成的列表为值,添加到字典里,如start_floor_rooms = {301:[1,70]} print(start_floor_rooms)
---运行结果--- 请输入起始楼层:1 请输入起始楼层室的尾号:(如01,02):08 请输入108的朝向(南北朝向输入1,东西朝向输入2):2 请输入108的面积,单位平方米:32 {108:[2,32]} 代码3: for value in DictName.values(): # value的名字可以自行另取 # DictName是要遍历的字典的名称 # .values():是固定的用法 代码4: for k,v in DictName.items(): #遍历字典的键值对,k对应键,v对应值 #k,v 的名字可以自己取,DictName是字典名 15-19关常见问题解决办法 1、vscode打开拖入文本文件乱码问题: 答: 切记乱码问题,都是解码方式与编码方式不匹配原因导致,如果是直接拖拽文件到vscode乱码,那么就更换文件的编码:
选成utf-8就可以解决! 2、解码之后出现\ufeff
答:windows系统会出现的utf-8有无BOM的问题,这种情况encoding后面的解码方式更换成‘utf-8-sig’即可 3、课堂上这个为什么读取出来多遍难念的经?
课堂代码运行一遍就会写入一遍难念的经,有时候网络延迟问题或者多次点击写入,会导致多次写入 4、魔法学院的文档读入写入练习:
5、15关课后读取图片练习:
这里面因为图片都给大家内部嵌入了我们的在线编辑器系统里面,所以大家直接用相对路径即可~,注意读取模式,跟写入模式的选择 6、绝对路径,相对路径的区分使用办法~ 经常我们会报错找不到文件,或者17关二维码的额wrong picture。这两个问题我们都要首先查看下我们的地址,通常建议更换绝对路径 例如: 我要找到这个scores4,文本文档的绝对路径,右键鼠标点击属性
如图所示,我们现在可以开始拼合绝对路径,1+2中间用\分隔即可 得到: C:\Users\user\Desktop\scores(4).txt 因为编程里面 \ 如果不说明会被默认为转义字符,所以我们还要操作一下这个\ 方法一:全部改成 \\ 就是 :C:\\Users\\user\\Desktop\\scores(4).txt 方法二: 路径前面加上r ,默认让后面\ 都不转义:r'C:\Users\user\Desktop\scores(4).txt' 7、罗恩分数偏移量就检索不理解:
在我们测试出换行符长度是1之后,我们想要精准的区分分数部分 跟名字部分,因为姓名有两个字,跟三个字的。我们没办法精准定位,但是分数都是3位,于是采用倒数偏移量定位,确定名字的最后一位一定是-5偏移量,同时我们还可以确定名字第一位一定是0偏移量,所以可以准确区分。 8、古诗词默写:
9、倒计时代码不理解的地方: 倒计时的原理就是,利用time模块读取当前时间,通过遍历不断的一次次打印,因为改写参数不进行换行,重复打印然后退格,实现倒计时效果
10、如何使用vscode (强烈建议观看!) 纠结找不到图片的童鞋! 首先要在vscode文档区创建自己的文件夹:
点击箭头这个创建文件夹,如图我创建了演示文件夹 然后点击演示文件夹,点击箭头左边的图标,创建一个文件~
新建的文件都是文本文档,要想弄成代码可执行的文件,要另存修改格式为python
保存之后就可以输入自己的代码了~ 切记运行代码一定要在代码框右键python终端运行python文件
如果选错远了运行选定行,那么就会进入交互模式,也就是代码一行行执行,代码块结构运行会报错
当你的终端显示哪里出现三个大于号,就是进入了交互模式这时候在三个大于号后面输入: exit(),记住一定要英文格式然后回车,退出交互模式,重新正确运行 安装模块可以在终端框里输入命令进行安装:
然后回车即可下载~ 三百七十三 阅 目录 - 5、判断文件是不是被当成模块调用,来执行相关语句:
山顶复习【0-19关】 学习群不解散的话,之后仍然可以查询群聊天记录~因为内容会比较多,所以建议大家先禁言,助教会给大家准备答疑时间。这样大家爬楼会比较方便一点 下面助教带大家把0-9关的知识点复习一下哟 #0-4关 0-4关相对比较简单,所以助教会讲得快一点哦~
#第0关 print函数 print()函数由两部分构成:1. 指令:print;2. 指令的执行对象:在print后面的括号里的内容。 我们对电脑下指令——把括号里的内容打印给我瞧瞧
*单引号,双引号、三引号 1)单引号‘ ‘和双引号“ “:直接输出 2)三引号‘‘’ ‘’‘:换行 *转义字符 “换行”的转义字符是\n *变量命名规范: 2、变量的命名规范 1.只能用一个词 2.只能包含字母、下划线和数字 3.不能以数字开头 4.尽量描包含的内容 转义符号: 1、\n(换行) 例子:print('把我的幻影和梦\n放在狭长的贝壳里\n柳枝编成的船篷\n还旋绕着夏蝉的长鸣\n拉紧桅绳\n风吹起晨雾的帆\n我开航了') 以下是拓展:(只做了解,不用掌握使用方法)
#第1关 #第1关:主要内容是数据类型和数据拼接 数据类型分为;int,str,float 数据拼接需要数据类型一致 需要注意的是:input默认输出为字符串,在后面与int做条件判断的时候,需要先转换数据类型为int(input());同时数字做数据拼接时,需要使用str(number) #第2关 第2关:主要内容是单向判断,双向判断,多项判断 单向判断为:if 双方判断为:if……else 多项判断为:if……elif ……elif……else 需要注意的是: if……if……if与if……elif……elif的区别,执行的模块数量,if……if,是不管前一个测试是否通过 条件的判断: and 和 or的使用, and,表示且,满足a且满足b条件,则为True,进入下一步; or,表示或,表示满足a或者满足b,则为True,进入下一步: 这里有些同学有不恰当使用and的栗子哟~ 比如: #知识点:条件and和or x=input('请给小狗起个名字:') if x == '小狗' and x =='汪汪': #正确应为if x == '小狗' or x =='汪汪': #or表示两个条件满足一个,就执行下一步 #and表示两个条件同时满足,才进行下一步 #第3关 #第三关的重点是input函数,也就是输入。 1)a=input(),把输入的值给变量; 2)input是输入,print是打印,两个是不一样的哟。 举个栗子🌰 teacher=input('我最喜欢的助教是:') print('我最喜欢的助教是:'+teacher) #这次山顶被问到的一个问题是:a=print(2),则a为None,因为print函数不返回值。 这里是前四关,比较简单,所以过的比较快,这里有需要提问的同学嚒 #第4关 #列表 #列表:[],元素,包容多种数据类型,有序((一般英文表示为list) #列表切片,使用‘’符号 list2 = [5,6,7,8,9] print(list2[:]) #输出结果为[5,6,7,8,9],冒号:表示取全部 print(list2[2:]) #这里是从偏移量为2的算起(左取),所以对应输出的为[7,8,9],冒号:表示取后面所有 print(list2[:2]) #这里是到偏移量为2(右不取),所以对应输出为[5,6],冒号:表示取前面所有 print(list2[1:3]) #这里对应的为偏移量1(左取)到偏移量为3(右不取),所以输出对应为[6,7] print(list2[2:4]) #这里对应的为偏移量2(左取)到偏移量为4(右不取),所以输出对应为[7,8] #增加或删除元素 #增加元素,使用append函数,格式是列表名.append( ): a = [1,2,3] b = [4,5,6] b.append(a) print(b) #输出结果为:[4, 5, 6, [1, 2, 3]],将列表作为一个元素添加 注意区别于extend()函数 d = [4,5,6] c= [1,2,3] d.extend(c) print(d) #输出结果为:[4, 5, 6, 1, 2, 3] #删除元素, 方法一:使用del函数,格式是del 列表名[元素的索引]),可删除任何位置的列表元素 a=[5,6,7,8] del a[3] print(a) 方法二:使用pop函数,将元素从列表删除,并接着使用他的值 a=[5,6,7,8] a1=a.pop(3) print(a1) 拓展1:元组 Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。(一般英文表示为tuple) 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。 tup1 = ('physics', 'chemistry', 1997, 2000) tup2 = (1, 2, 3, 4, 5, 6, 7 ) 元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例: tup1 = (12, 34.56) tup2 = ('abc', 'xyz') tup3 = tup1 + tup2 print(tup3) #则打印结果为(12, 34.56, 'abc', 'xyz') 列表相关函数 sort和sorted函数排序:区别在于sort为永久性,sorted为临时性 详情请查看链接:https://blog.csdn.net/guoyang768/article/details/84428171 其他列表常用函数还有:https://www.cnblogs.com/yi-xixi/p/10973686.html (这里仅做了解不要求掌握) #字典 #字典:数据存在一一对应情况;{};键具备唯一性,而值可重复 #新增键值对要用到赋值语句字典名[键] = 值 dic={'七七':180,'Billy':190} dic['班助']=220 print(dic) #打印结果为{'七七': 180, 'Billy': 190, '班助': 220} #字典删除元素 dic={'卡西':180,'Lin':190} del dic['Lin'] print(dic) #输出:{'卡西': 180} #字典增加元素 dic={'七七':180,'Billy':190} dic['班助']=220 print(dic) #打印结果为{'七七': 180, 'Billy': 190, '班助': 220} #方法items()方法:字典里面提取key和value(键和值)的方法 A={'绿色':1,'红色':2,'黄色':3} for key,value in A.items(): #print(key) #输出绿色,红色,黄色 print(value) #输出1,2,3 #字典使用keys(方法):字典提取键 A={'绿色':1,'红色':2,'黄色':3} for key in A.keys(): #print(key) #输出绿色,红色,黄色 #字典使用values方法:字典提取值 A={'绿色':1,'红色':2,'黄色':3} for value in A.values(): print(value) #输出1,2,3
items()函数的用法:https://blog.csdn.net/u011475210/article/details/77770145 #习题讲解 list1 = [{'嫉妒':'envy'},{'恨':'hatred'},{'爱':'love'}] print(list1[2]['爱'])
# 第一步:取出列表中的第三个元素(list1[2]),字典{'爱':'love'}; # 第二步:取出list1[2]中键'爱'所对应的值,即'love’(list1[2]['爱'])。
dict1 = {1:['cake','scone','puff'],2:['London','Bristol','Bath'],3:['love','hatred','envy']} print(dict1[3][0])
# 第一步:取出字典中键为3对应的值(dict1[3]),即['love','hatred','envy']。 # 第二步:再取出列表['love','hatred','envy']中的第一个元素(dict1[3][0])。
tuple1 = ('A','B') list2 = [('A','B'),('C','D'),('E','F')]
print(tuple1[0]) print(list2[1][1])
# 从代码里,也可看出:1.元组内数据的提取也是用偏移量;2.元组也支持互相嵌套。 townee = [ {'海底王国':['小美人鱼''海之王''小美人鱼的祖母''五位姐姐'],'上层世界':['王子','邻国公主']}, '丑小鸭','坚定的锡兵','睡美人','青蛙王子', [{'主角':'小红帽','配角1':'外婆','配角2':'猎人'},{'反面角色':'狼'}] ] print(townee[5][1]['反面角色']) #不清楚的时候,我们可以用print去尝试 #首先townee是一个列表,最外面的[]得知 #其次为列表内嵌套了字典和列表,我们分层应该为: townee = [ {'海底王国':['小美人鱼''海之王''小美人鱼的祖母''五位姐姐'],'上层世界':['王子','邻国公主']}, #偏移量为0 '丑小鸭', #偏移量为1 '坚定的锡兵', #偏移量为2 '睡美人', #偏移量为3 '青蛙王子', #偏移量为4 [{'主角':'小红帽','配角1':'外婆','配角2':'猎人'},{'反面角色':'狼'}] #偏移量为5 ] #print(townee[5]),输出结果为[{'主角':'小红帽','配角1':'外婆','配角2':'猎人'},{'反面角色':'狼'}] #分层为: [{'主角':'小红帽','配角1':'外婆','配角2':'猎人'},#偏移量为0 {'反面角色':'狼'}] #偏移量为1 #print(townee[5][1]),输出结果为{'反面角色':'狼'} #最后就是字典的提取值的方法啦 #第5关 #for和while循环 #循环:把一件事执行很多遍 #一般由两种语句,1)for...in...循环语句;2)另一种是while循环语句 #for循环
常见用法如下: #1.1)for in循环与列表 for i in [1,2]: print(i) #遍历列表,所以这里的i为依次遍历的元素哟
#1.2)for in循环与字典 dict = {'日本':'东京','英国':'伦敦','法国':'巴黎'}
for i in dict: print(i) #遍历字典,这里的i为字典的键 print(dict[i]) #dict[i]为字典的值的提取方式,所以这里打印为的字典的值
#1.3)for i循环与字符串 #注意这里不可以为浮点或整数 for i in '吴承恩': print(i)
#2.for和range函数搭配 # 使用range(x)函数,就可以生成一个从0到x-1的整数序列,类似[a,b) #for i in range(0,10,3):,生成从1,10,间隔为3的序列 for i in range(0,10,3) print(i) #所以这里的i输出为0,3,6,9 #while循环 一般格式为 n=某个值 while 条件: 执行语句
#习题讲解 方法一: man = '' # 注:''代表空字符串,作用是个变量定义 while man != '有': #注:!=代表不等于 #也就是空字符不等于有,所以满足条件,进入循环,开始input输入 man = input('有没有愿意为小龙女死的男人?没有的话就不能出古墓。') print('小龙女可以出古墓门下山啦~')
#方法二: man = '没有' # 注:''代表空字符串 while man == '没有': #注:!=代表不等于 #进入循环,需要满足条件,所以最开始的定义,给了'没有' #满足条件进入循环 man = input('有没有愿意为小龙女死的男人?没有的话就不能出古墓。') print('小龙女可以出古墓门下山啦~') password = '' # 变量password用来保存输入的密码 while password != '816': password = input('请尝试输入密码:') #因为password赋值为input时,input默认输出为字符串类型,所以上面条件需要加引号 print('欢迎回家!') 当我们【工作量确定】的时候,我们就可以让for循环来完成重复性工作。 反之,要【工作量不确定时】可以让while循环来工作。
#课后习题 #方法一:使用for循环和pop函数 students = ['小明','小红','小刚'] for i in range(3): student1 = students.pop(0) # 运用pop()函数,将偏移量为0的元素赋值给变量student1,也就是,把第一个座位的同学提取出来。同时更新了列表 students.append(student1) # append函数,将元素添加到列表尾,将移除的student1安排到最后一个座位。 print(students) #打印列表 #方法二:使用while循环和pop函数 students = ['小明','小红','小刚'] i=0 while i<3: i=i+1 student1 = students.pop(0) # 运用pop()函数,同时完成提取和删除。 students.append(student1) # 将移除的student1安排到最后一个座位。 print(students) #方法三:for循环和切片 students = ['小明','小红','小刚'] for i in range(3): student1 = students[0] students = students[1:] students.append(student1) print(students) #方法四:while循环和切片 students = ['小明','小红','小刚'] i=0 while i<3: i=i+1 student1 = students[0] students = students[1:] students.append(student1) print(students) #第6关 布尔值和四种语句 #第6关的主要内容为:布尔值和四种语句 #布尔值:True和False(一般条件为True则继续循环,条件为False则结束循环) 布尔值的其他情况
#四种语句 break语句,用法如下
i = 0 #给i赋值,定义变量 while i<5: #循环条件,当满足i小于5时,持续循环 print('明日复明日') #满足条件则进行下一步 i = i+1 #更新i的值,以便打破循环条件 if i==3: # 当i等于3的时候触发 break # 结束循环 continue语句:当某个条件被满足的时候,触发continue语句,将跳过之后的代码,直接回到循环的开始。用法如下:
pass语句:跳过,不执行任何语句 else不但可以和if配合使用,它还能跟for循环和while循环配合使用
#习题讲解 n = 0 #list_answer = {} list=[] #定义空列表 while True: n += 1 a = input('A,你认罪吗?请回答认罪或者不认:') b = input('B,你认罪吗?请回答认罪或者不认:') #list_answer[n]=[a,b] #字典增加键和键值的方法 list.append([a,b]) #列表增加元素的方法 if a == '认罪' and b == '认罪': #对囚犯的选择进行判断,打印对应的刑罚 print('两人都得判10年,唉') elif a == '不认' and b == '认罪': print('A判20年,B判1年,唉') elif a == '认罪' and b == '不认': print('A判1年,B判20年') else: print('都判3年,太棒了') break #print(list_answer) #print('第' + str(n) + '对实验者选了最优解。') for i in range(n): #for i in range(n),是取出0到n-1的序列 print('第' + str(i+1) + '对实验者的选择是:' + str(list[i])) #这里的list_answer[i]根据偏移量提取列表元素,i是for i in range(n)中i的取值 #print('第' + str(i+1) + '对实验者的最优选择是:' + str(list[i])) #因为囚徒困境(博弈论知识),的最优选择为【不认,不认】,所以输出列表的最后一次选择就可以 主要思路: 1)设置空列表,用于存储值 2)因为有不确定次数的囚犯回答,所以我们利用while循环 3)input输入囚犯回答,if……elif用于判断 4)打印结果
#第7关 总体思路: #1.1展示随机属性&随机生命值和攻击值 #1.2展示PK过程 #1.3展示每一局的PK结果,并设置三局两胜,也就是在每一局外面设置for i in range(1,4)的循环 #1.4展示三局两胜的最后PK结果,借助第三方变量,类似篮球积分 #1.5设置三局两胜在输入某个键时,是否继续循环,也就是while True部分 #随机展示敌我双方角色,生命值和攻击值(需要注意导入模块和定义变量)
#展示攻击过程
#开始判断敌我双方的胜利 #将一局判断循环3遍,达到三局两胜的情况,同时引入变量,开始积分(类似篮球赛)
引入player_victory记录分数,如果我方胜利,则+1分;如果敌方胜利,则我们-1分;否则平局不扣分,通过最后的分值是否为正,统计PK结果 #是否继续游戏
新的“格式化字符串”的方法:format()函数 # % 格式化:str % () print('%s%d'%('数字:',0)) print('%d,%d'%(0,1)) print('%d,%d,%d'%(0,1,0))
name1 = 'Python' print('I am learning %s'% name1) # 注:当只跟一个数据时,%后可不加括号,format()一定要有。 # format()格式化函数:str.format() print('\n{}{}'.format('数字:',0)) # 优势1:不用担心用错类型码。 print('{},{}'.format(0,1)) # 不设置指定位置时,默认按顺序对应。 print('{1},{0}'.format(7,8)) # 优势2:当设置指定位置时,按指定的对应。 print('{0},{1},{0}'.format(5,6)) # 优势3:可多次调用format后的数据。
name2 = 'Python基础语法' print('我正在学{}'.format(name2)) # format()函数也接受通过参数传入数据。 #第8关 第8关我们主要是了解一个学习方法
这里同学们要自己好好应用这些方法,去做好笔记。好记性不如烂笔头,自己梳理笔记,学习效果更好哦! 第9关 第9关我们学习了函数 什么是函数呢?
下面来讲讲怎样定义和调用函数 定义和调用函数 首先我们要定义函数,怎么定义函数呢?
比如: def 助教(名字): print(名字+'很棒哟!') return
第1行:def的意思是定义(define),greet是【函数名】(自己取的),再搭配一个括号和冒号,括号里面的name是参数(参数名也是自己取)。 第2行:def下一行开始缩进的代码是函数要实现的功能,也叫【函数体】。这里的函数体展现出的功能就是:打印出“name+ 早上好”这句话。 第3行:一个简单的return。函数内部一旦遇到return语句,就会停止执行并返回结果。没有return语句的函数,Python也会在末尾隐性地加上return None,即返回None值(return None可以简写为return。)
!!!定义函数只是将函数的内部功能封装起来(组织好),运行不会输出任何内容!!! 定义完函数之后,还需要调用才会执行函数内的语句~下面来讲讲怎么调用函数! 调用函数 怎么调用函数呢?在Python里,就是输入函数名和参数对应的值: def 助教(name): print('我最喜爱的助教是'+name) 助教('卡西') #调用函数,输入函数名助教()并输入参数'卡西' 助教('七七') #调用函数,输入函数名助教()并输入参数'七七' 助教('延君') #调用函数,输入函数名助教()并输入参数'延君' 调用函数最关键的是:得弄清楚这个函数有多少个参数,如何给参数赋值,这个过程在函数里叫做参数的传递(传参)。 有多少个参数(没有默认值)就要传多少个参数的值进去。 接下来讲一下函数的一些概念:参数、变量、return 函数重要概念 参数类型 主要的参数类型有:位置参数、默认参数、不定长参数。 【位置参数、默认参数】
参数可以替换! 【不定长参数】 不限定死数量,这时候【不定长参数】就能派上用场,即不确定传递参数的数量。 它的格式比较特殊,是一个星号*加上参数名
!!!默认参数也需要放在不定长参数的后面,即dessert=’绿豆沙'要放在*barbeque后面,否则传递的值会对应不上!!!
1、加了一个星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。 如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。 ('烤鸡翅', '烤茄子', '烤玉米'),这种数据类型叫做元组(tuple) 元组的写法是把数据放在小括号()中,它的用法和列表用法类似,主要区别在于列表中的元素可以随时修改,但元组中的元素不可更改。 2、加了两个星号 ** 的参数会以字典的形式导入。 详情可以点击链接了解:https://blog.csdn.net/weixin_38280090/article/details/85623286 return语句
如:
#最终输出是“嗯,人生才刚刚开始” main()函数内部分别调用了face()和body()函数,参数dream_face和dream_body传递给了face()和body()函数的参数name,得到返回值,并打印。
前面所有的return语句,都是返回1个值。 Python语言中的函数返回值可以是多个,而其他语言都不行,这是Python相比其他语言的简便和灵活之处。一次接受多个返回值的数据类型就是元组。
而元组与列表其实都是数据的“序列”,元组取某个位置的值的操作,与列表偏移量是一模一样的,即tuple[]
再来讲一下变量 变量作用域 第一点:在一个函数内定义的变量仅能在函数内部使用(局部作用域),它们被称作【局部变量】。 第二点:在所有函数之外赋值的变量,可以在程序的任何位置使用(全局作用域),它们叫【全局变量】。
!!!全局作用域中的代码中也不能使用任何局部变量!!! 建议局部变量和全局变量【不要】取相同的名字,以免混淆。 当变量在函数内时,就是局部变量,只能在这个函数内被访问; 当变量在函数外时,就是全局变量,可以在程序中的任何位置被访问 全局作用域中的代码中也不能使用任何局部变量。
也可以用global语句将变量声明为全局变量!!!【用global声明了全局变量,就可以在局部里面修改这个变量的值】
#课后练习 定义两个函数:第一个函数功能为根据工作月数返回奖金额,第二个函数功能为打印出'该员工来了XX个月,获得奖金XXX元'。 发放奖金的要求如下: 工作时长不满六个月,发放固定奖金500元。 工作时长在六个月和一年之间(含一年),发放奖金120元*月数(如8个月为960元) 工作时长在一年以上,发放奖金180元*月数 (如20个月为3600元) def bonus(month): if month < 6: money = 500 return money elif 6 <= month <= 12: money = 120 * month return money else: money = 180 * month return money
def info(name, month): gain = bonus(month) print('%s来了%s个月,获得奖金%s元' % (name, month, gain))
info('大聪',14) 好啦,山脚阶段课程的知识点的梳理就讲到这里,同学们有哪里还不明白的吗?可以先在群里讨论哈~下午继续复习山腰、山顶阶段的知识~
首先,因为山腰课程有两个实操,分别是10、14关。这两关的实操因为涉及的知识点不太多,助教不做知识点的讲解,到后面有疑问的集中答疑 # 我们直接从11关的知识开始 第11关知识讲解 # 11关的课程目标是学会debug的方法以及如何避免bug # 在我们运行程序时,如果遇到报错,会有三个关键信息 # 1)line x代表这个bug出现在第x行,在Debug的时候,可以优先从第x行开始检查; # 2)^代表bug发生的位置 # 3)错误类型,如SyntaxError指的是语法错误。对英文不熟悉的直接复制查百度。 # 当我们遇到程序报错的时候,我们可以根据自检清单来进行排查 #
# 这个常见报错类型同学们一定要看看:https:///docs/eyTFT6cZL68IhU6z/ 《那些年我们遇到的报错》,可复制链接后用石墨文档 App 或小程序打开 # 因为同学们经常会在打代码的时候,犯粗心的错误,粗心是同学们最常见的第一种报错类型 # 所以在敲代码的时候就要细心一点啦,像缺符号特别是少一个括号,缩进,没有定义变量这种错误~都是可以避免的 # 第二种,就是知识不熟练 # 这个需要同学们多去复习知识点,熟悉具体的使用方法 # 第三种,思路不清 # 遇到代码多的时候,不知道到底哪里出错了 # 这种情况,可以在关键步骤print出来,看是否达到我们所期望的结果,以此来揪出错误的那一步 # 或者使用#号把后面的代码注释掉,一步一步运行,可以帮助排除错误 #
# 第四种,被动掉坑 # 指有时候你的代码逻辑上并没有错,但可能因为用户的错误操作或者是一些“例外情况”而导致程序崩溃。例如: #
# 在这个程序中,当输入的不是纯数字时,会报错ValueError:invalid literal for int() with base 10 : # 因为,int()函数不能接受非数字的字符串。 # 像这种情况,我们可以用到try...except语句 #
#
#
# try...except语句可以用三种用法,这个应该不难理解 详细的用法可以参考这个链接:https://blog.csdn.net/chenmozhe22/article/details/82850001 # 11关的知识点不难,主要是希望同学们能学会自己根据报错信息去找错误 # 养成自己debug的习惯 # 尤其到了山顶的课程,更需要自己依靠自己去找解决方法 # 这也是学习编程过程中很关键的技能 第12、13关知识讲解 # 12关、13关我们学习的面向对象编程,是山腰学习中最重要的知识内容 # 学习这两关的目标是 # 1)了解何为对象 2)区分变量与类属性,函数与类方法 3)掌握类的实例化及初始化函数 4)熟练继承与子类定制 # 涉及到的难点有: 类的实例化,初始化函数的改写,继承的用法 # 首先我们要知道,什么是面向对象编程 # 面向对象编程就是以对象为中心,将一组对象组成程序。使用于较复杂,尤其需要持续更新的代码场景。 # 比如甲乙丙丁都做一道西红柿炒蕃茄的菜(做的味道都不一样),这个做菜的程序就是面向过程。 # 甲写了一份西红柿炒蕃茄的菜谱,乙丙丁按照这个菜谱步骤做出味道一样的西红柿炒蕃茄(不管谁按这个菜谱来做,都是一样味道),这个程序叫做面向对象。 # 相信同学们在学习中也能感受到,使用类的调用是很方便的一件事情 # 那么类是什么? # 类,是一个函数包。类中可以放置函数和变量,然后类中的函数可以很方便的使用类中的变量,(也就是类方法可以调用类属性) # 类中的 函数 叫 方法,类中的 变量 叫 属性 # 这个需要搞清楚哦 # 创建类的时候,类名首字母要大写 # 且后面不要忘记冒号“:” #
#
# 那么,方法和属性我们知道了,那什么是参数呢? # 参数是,我们在定义函数的时候,需要传递给类方法的东西 # 我们举个例子 #
# 在这里的代码中,我们在定义函数的时候,留了一个需要手动传递参数的位置 # 所以在调用类方法的时候,需要手动设置一个参数 # 如果没有设置参数,或者参数设置多了,都会报错 # 但有一种情况可以不手动设置参数 # 那就是在定义方法的时候,将需要的参数设置为默认参数 #
# 在同一个类里面,不同方法之间,还可以实现方法的调用 # 举个栗子 #
# 在方法 live()中,就调用了方法 born() # 这边也举一个实例调用类方法的例子 #
# 左边是错误,右边是正确的例子 # 左边的错误在于 1:在类方法下调用其他方法的时候,先进行了实例 2:调用类方法的格式错误 # 顺着这个例子,我们接着讲到,类的实例化是什么?实例怎么使用? # 类是对象的模板,可以复制出多个对象,这个过程叫实例化 # 格式 : 实例名=类名() #
# 这里要注意,类实例化的时候,类的括号不能丢 # 被创造出来的实例与类一模一样,但是它是独立的对象 # 调用类属性和类方法的格式分别为: 调用类的属性:实例名.属性; 调用类的方法:实例名.方法() # 这里给大家展示一下例子 #
# 这个例子属于,在类外部调用类的属性 # 我们用print语句将my_computer这个实例的screen这个属性打印出来 # 属性可以在外部调用,也可以在类的内部调用 # 当在类的方法的内部想调用类的属性或类的其他方法时,就要采用self.属性名或self.方法名的格式。(相当于改变了作用域) #
# 有同学问,为什么实例调用方法时不用传参,定义时不是有个参数self吗? # 这就是参数self的特殊之处:在定义时不能丢,在调用时要忽略(就是占位的作用) # self的作用是,self会接收实例化过程中传入的数据,当实例对象创建后,实例便会代替 self,在代码中运行 # 通俗一点理解,只要记住,加上self.前缀的类属性和类方法,准确来说叫实例属性和实例方法,可以在类下的不同类方法中实现调用 # 那么,实例的对象,和类之间有什么联系呢 # 首先,实例属性和类属性: 1)修改类属性,这会导致所有实例属性变化(因为类是模板); 2)修改实例属性,但这不会影响到其他实例,也不会影响到类。因为每个实例都是独立的个体。 #
# 其次,实例方法和类方法: 1)重写类方法,这会导致所有实例方法自动被重写; 2)实例方法不可重写 #
# 再跟大家讲一下,如何修改类方法 # 上面也说了,类方法可重写,实例方法不可重写 # “重写类方法”分成两个步骤: 1)在类的外部写一个函数, 2)把这个新函数的名字赋值给 类.原始函数: #
# 注意:这里的赋值是在替换方法,并不是调用函数,所以【不要加上括号】 # 初始化函数 # 初始化函数(方法),也叫构造函数,它的意思是,当你创建一个实例的时候,这个函数就会被调用(自动执行)。 # 初始化函数的写法是固定的格式:中间是“init”,这个单词的中文意思是“初始化”,然后前后都要有【两个下划线】,然后__init__()的括号中,第一个参数一定要写上self,不然会报错 # 也就是写成def __init__(self): #
# 我们一般会用初始化函数来做什么呢? # 在初始化方法内部完成类属性的创建,为类属性设置初始值,这样类中的其他方法就能直接、随时调用。不需要再调用__init__() # 举个栗子 #
# 在这个类中,一旦调用,就会自动执行初始化函数创建类属性 # 在初始化函数的定义时,也可以设置需要传递的参数位置 # 在实例化类的时候,可直接手动传入参数 #
# 继续讲最后一个知识,类的继承 # 类的继承很大程度也是为了避免重复性劳动。比如说当我们要写一个新的类,如果新的类有许多代码都和旧类相同,又有一部分不同的时候,就可以用“继承”的方式避免重复写代码; # 同理,在类的继承后,子类重写初始化函数时调用父类的初始化函数,也是因为许多代码都和旧类相同,又有一部分不同的时候,就可以用调用的方式避免重复写代码; # 子类创建的实例,同时属于父类 父类创建的实例,不属于子类; #
# 这个例子属于类的定制和调用,能够理解这个代码,其实对于类的继承最核心的知识就掌握了 # 上面提到,子类重写初始化函数,其实在子类中,可以重新任何方法 # 但我们还是以重新初始化函数为例子 #
# 在这个代码中,Knight类继承了Role类 # 并重新初始化函数,修改了类属性 # 这里可以改为另一种写法,也就是重写子类初始化函数时,调用父类的初始化函数。或者可以理解为父类方法的继承 #
继续举栗子 #
# 先看这个,没有继承的类方法调用 #
# 这个子类继承后,修改了方法,再进行调用 #
# 同学们在自己敲代码的时候,遇到不知道变量到底有没有被修改这些情况的时候 # 就可以通过print去打印看看 # 这个过程中也有助于自己熟悉打代码的感觉,熟悉句式的使用 # 多练,多练 下面给大家讲解一下10、12、13关课后习题哈,给你们巩固一遍知识 第10关课后习题讲解 ### 我们第十关的练习是和电脑进行剪刀石头布 ### 这里会用到的知识点有: 1. random模块的使用 2. while循环实现输入判断 3. if条件语句进行条件判断输出结果 在进阶练习中还会涉及到一个新知识: 4. index()函数的使用 ### 1.random模块大家应该不陌生,我们在山脚第七关的实操课中也有学习过 不过之前学习到的是random.randint()的使用,这次我们要用到的是random.choice() random.choice()是random模块中有个随机选取一个元素的方法,我们在练习的使用上,是从列表punches = ['石头','剪刀','布']随机选取一个元素,作为电脑的出拳选择 ### 2. while循环实现输入判断 while user_choice not in punches: # 当用户输入错误,提示错误,重新输入 print('输入有误,请重新出拳') user_choice = input() while user_choice not in punches 意思是当user_choice不在列表punches中时,进行循环 在循环下,给user_choice重新赋值~再进行循环,直至输入正确 ### 3. if条件语句进行条件判断输出结果 这一部分应该不难理解,就是列出可能会出现的各种出拳组合,根据不同的组合情况进行结果的输出
但是我们能看出,这样的方法虽然很直观,也能达到目的,但是不够高级,不够简洁 所以在进阶练习中,我们学习到一个新知识index() 函数 ### 4.index() 函数用于找出列表中某个元素第一次出现的索引位置 语法为:list.index(obj),obj为object(对象)的缩写。 简单的看一下这个例子,了解用法
在课程上,可能大家都比较难理解注释里所讲的索引减1是什么意思
这里我们可以结合这张图解一起来看 当电脑出拳为布,索引为2,若玩家想赢,则需出拳为剪刀,索引为1 punches.index(computer_choice)-1 则是将电脑的索引减1,才与玩家的索引相等 当电脑出拳为石头,索引为0,若玩家想赢,则需出拳为布,索引为2 这里就需要注意了,布的索引从正数为2,从倒数则是-1 所以石头的索引0-1=-1,也就是布的索引 第12关课后习题讲解 ### 第12关的课程练习是对课程的一个拓展,其实难度不大,也没有太多同学反馈有不理解的问题。所以助教也会把整个逻辑简单的讲一遍 ### 课程要求是:新建一个方法,让实例只要调用一个方法,就能打印出两个信息。 这里我们会用到初始化函数,还有在函数内调用类属性 ### 我们先来看直接调用类的实现方式
这里我们定义了一个类,类下包含一个初始化函数,两个普通方法 在初始化函数中,我们会给它传递两个参数,并将这两个参数赋值给self.hometown和self.region 这里有同学的疑问是,为什么要把参数重新赋值呢?为什么不可以直接使用? 因为hometown和region作为参数的时候,是只在该方法下有效的,而其他方法不能直接调用这个参数 如果想调用,就要用到重新赋值给一个变量,且这个变量需带有self.的前缀,这样才能实现在不同的类方法下调用该变量(也叫属性)
所以我们看到在后面的两个方法中,分别对两个属性进行了调用 看上图的代码,最后的调用中,只调用了Chinese()这个类,这样的运行结果,其实没有实现题目的要求 因为单单调用Chinese类的时候,只会执行初始化函数,而不会再进行其他的操作 ### 既然题目说了,要新建一个方法,且只调用一个方法,就能打印出两个信息。那么我们就需要用一个main()来把打印两个信息的方法再封装起来 完整代码如下
在这里的main()方法下,按顺序调用 self.born()和 self.live()两个方法 所以当我们在最后调用的时候,只需要调用main()就可以同时执行另外的两个方法了,运行结果就是根据调用时手动传递的参数打印出两个语句 ### 助教再讲一下第二个练习吧,简单讲一下,其实跟第一个练习相似,只不过在某个方法中还加入了一个循环,但是逻辑上理解是一样的
这道题助教从函数执行的顺序开始讲 首先执行 robot1 = Robot() 进行实例化,实例化的同时也执行了函数的初始化函数
看我把最后一句注释掉,只执行robot1 = Robot() 的时候,只执行初始化函数的部分 当我把最后一句加上时,实例robot1调用方法say_wish()
在say_wish()下,先用input输入并赋值给wish 这里有同学问,为什么这里的wish不用加self.哇? 是因为wish这个变量,它只在该方法下进行使用,你看它不需要在其他类方法被调用,对吧。所以是可以不加self.的 所以最后通过一个循环,打印三遍,完成题目要求 第13关课后习题讲解 ### 来简单的讲一下13关的习题吧,13关我们学到的主要知识就是 【类的继承】 考虑到同学们对继承逻辑的理解会稍微比较绕,所以13关的习题也设置得比较简单,目的也是让同学们以最直观的方式进行继承的操作 而稍微复杂的操作,我们会在14关的实操课中去学习 来看习题,第一个目标和要求
这个题目在练习中已经给出了代码,但是同学们也要理解
首先这里Teacher类和Father类个字有两个属性,其中一个同名属性face 我们用time1 和 time2分别对两个类进行实例化,再调用各自的face属性
记得在创建实例的时候,格式是 实例名 = 类() 括号不能丢 然后用 实例名.属性 的方式调用了类的属性,并用print进行打印 第二部分,课程要求是
代码如下
### 我们先定义了 class TeacherMore(Teacher, Father): pass 这里按照多重继承的逻辑,会优先继承Teacher这个父类,在这个类下,pass的意思是完全继承,不做修改 ### 再者,我们定义了 class FatherMore(Father, Teacher): face = 'gentle' 这里按照多重继承的逻辑,会优先继承Father这个父类,在这个类下,对属性face进行了重新赋值,修改为‘gentle’ 我们用time3 和 time4分别对两个子类进行实例化,再调用各自的face属性 time3是子类TeacherMore()的实例,因为没有重新赋值face,所以优先继承了Teacher这个父类的face属性,打印为serious time4是子类FatherMore()的实例,因为重新赋值了face,所以此时打印重新赋值后的face属性,打印为gentle ### 助教继续讲第二个进阶练习
先看初级版本,在类下两个方法,一个初始化方法,一个普通方法 初始化的作用是一般会用来执行一些默认的操作,比如把参数赋值,这样当调用类的时候,则默认执行初始化函数,不用手动进行调用 而普通方法则是实现特定功能的调用,这里的count_time()则用来计算效率 同学会问,为什么在init里,要重新对参数赋值呢,self.的作用是什么 这里对参数重新赋值到一个变量,目的是为了在其他的类方法进行调用,只有加了self.前缀的才能进行调用哦 如果没有加self. , 则只能在该方法下使用
看第一个实例,调用了类Student,并传入了一个参数给name 在init中,因为其他的参数都是默认参数,所以调用的时候只传参给name即可
第二步,实例student1调用类方法count_time()并传入两个参数,并打印属性self.time_effective,具体逻辑如上图
在实例调用某个属性的时候,格式是 实例名.属性名,此时不用加self. ### 接下来是升级版
子类Programmer()继承了父类Student(),并进行了类方法的重写(定制)
子类重写初始化函数,修改了原参数中job的默认值,并在在函数下调用了父类的初始化函数,参数传递如上图
子类重写count_time方法,修改了原参数中rate的默认值,参数传递如上图
创建实例student1和student2,参数传递如上图
实例student1和student2分别调用count_time()方法,参数传递如上图
15关知识点 编码: 什么是编码? 计算机本来是一个只认识0和1的计算机,为了更好的交流,这种从人类语言到计算机语言转换的形式,叫做编码表。数字或者字母在计算机储存的时候需要转换成二进制,每个人转换的规则就叫做编码。 人类语言 → 计算机语言 encode() 计算机语言 → 人类语言 decode() 二进制: 通俗来讲就是0和1,因为计算机只认识这两个,所以通过不同的排列来表示相关的状态,不需要纠结太多,那是计算机的问题,我们通常有编码表转换成人类语言,如果非要关心二进制,跟10进制转化,可以善用百度上面有现成的转换计算器,非科班出身的我们懂得这回事就可以啦`
文件读写: python代码调用电脑文件的主要功能。 文件读取: 牢记步骤:打开文件 —— 读取文件 —— 关闭文件 模板写法:
第二行代码是把读取到的内容存到了filecontent变量里面,下面打印出来,read()函数通常是整个读取出来,但是不同情况时候我们需要按行读取,也就是一行行,这里要利用到readlines()函数其他都不会变,替换read()函数就可以 切记用open函数最后要close()文件 写入文件:
同样要记住最后要close() 不过如果加一个with关键字,比如withopen那么写完之后自己就会关闭,不需要close() 当然写入的数据多种多样,我们要更换写入或者读取的模式,记住下面这个表很关键!!!
其他知识点: split()函数: 按照空格分割字符串,str.split() join()函数: 把字符串合并,用法是str.join(sequence),str代表在这些字符串之中,你要用什么字符串连接,在这里两个例子,一个是空字符串,一个是横杠,sequence代表数据序列,在这里是列表a writelines() 因为write()的参数必须是一个字符串,但是有时候我们要写入别的内容,所以用到writelines()这后面的参数可以是列表 16关:模块的调用(明白底层原理,学会使用即可) 模块: 什么是模块? 最高级别程序组织单元,通常我们调用的模块都是写好的py文件,里面有各种变量,函数,类 等可执行的语句 调用模块: import 语句: 1、最常见的,import 模块名 例: import random random.randint ;(代码里面调用模块里面方法的格式,模块名.方法名,这里面randint是模块里面写好的方法,我们学会调用就ok,明白方法的功能) 2、import 模块名 as 简写: 例: import random as ra ra.randint;后面就可以利用ra代表random 3、导入多个模块: 例: import a,b,c ;(表示同时导入a,b,c三个模块) 4、从模块中只导入一个指定部分: from...import.... 例:
5、判断文件是不是被当成模块调用,来执行相关语句: if_name_== '__main__'
自学模块: 如果英文好的同学,可以直接阅读官方文档:https://docs./3.6/library/random.html 或者也可以直接百度搜索。 csv模块: 简易版excel,也是表格文件。csv模块的用法:
17关邮件 写在前面: 这一关重在应用,因为涉及到跟邮箱服务器连接问题,所以这里之后的代码要懂得,无法实现效果不一定是代码问题,比如还有可能邮箱服务器关闭了你的连接端口,很有可能同一段你写的代码别人可以发送成功,你这里就失败。 不要纠结,不要难过,这个锅甩给邮箱公司 这里我们学会利用代码实现固定功能,重要的是模板的套用! 成功发送的同学也不要开心起来就发个没玩,更加不要写循环发送,这样不止会导致封掉端口,还会给邮箱服务器带来很多没必要的负载~ 我们尝试过理解应用就好,大家都是善良的人,要做有爱的事! # smtplib 用于邮件的发信动作 import smtplib from email.mime.text import MIMEText # email 用于构建邮件内容 # 发信方的信息:发信邮箱,QQ 邮箱授权码 from_addr = 'xxx@qq.com' password = '你的授权码数字' # 收信方邮箱 to_addr = 'xxx@qq.com' # 发信服务器 smtp_server = 'smtp.qq.com' # 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码 msg = MIMEText('send by python','plain','utf-8') # 开启发信服务,这里使用的是加密传输 server = smtplib.SMTP_SSL(smtp_server) server.connect(smtp_server,465) # 登录发信邮箱 server.login(from_addr, password) # 发送邮件 server.sendmail(from_addr, to_addr, msg.as_string()) # 关闭服务器 server.quit() 本关卡具体实操项目: 重点说一些易错点: 1、
缺少host参数,这里要加上smtp_server也就是上面代表的'smtp.qq.com' 2、
授权码问题,要自己邮箱开启pop3服务,记住授权码不要加空格 3、
端口问题,qq邮箱的话建议试用465, 465频率比较高,或者25 多换一下这个是默认的 4、
报错无法解码,可能是python文件执行路径存在中文命名,彻底修改或者新建电脑用户(重新搭建python本地环境,比较麻烦) 第18关 一、流程图 顺序结构: 三种图形(带方向的线段,椭圆形,长方形) 解释: 带方向的线段-将流程图中的图形元素连接起来表示流转方向,可在线上添加备注文字 椭圆形-流程图的开始和结束 长方形-流程图中的主要表达的元素,表示一个动作(业务动作、功能动作等) 条件结构: 四种图形(带方向的线段,椭圆形,长方形,菱形 解释: 带方向的线段-将流程图中的图形元素连接起来表示流转方向,可在线上添加备注文字 椭圆形-流程图的开始和结束 长方形-流程图中的主要表达的元素,表示一个动作(业务动作、功能动作等) 菱形:表示逻辑判断,一般会连接Yes或No,两条分支流程 循环结构: 四种图形(带方向的线段,椭圆形,长方形,菱形) 解释: 带方向的线段-将流程图中的图形元素连接起来表示流转方向,可在线上添加备注文字 椭圆形-流程图的开始和结束 长方形-流程图中的主要表达的元素,表示一个动作(业务动作、功能动作等) 菱形:表示逻辑判断,一般会连接Yes或No,两条分支流程 ***循环有两种情况,一种是条件判断后进行循环(菱形),一种是结束某个流程后进入循环(长方形) 第19关 项目解示 代码一: import csv #调用csv模块 with open('assets.csv', 'a', newline='') as csvfile: #调用open()函数打开csv文件,传入参数:文件名“assets.csv”、追加模式“a”、newline=''。 writer = csv.writer(csvfile, dialect='excel') # 用csv.writer()函数创建一个writer对象。 header=['小区名称', '地址', '建筑年份', '楼栋', '单元', '户室', '朝向', '面积'] writer.writerow(header) #用writerow()函数将表头写进csv文件里 (1)newline='',是为了解决写入时CSV文档出现的空行 (2)dialect='excel',是默认的编码格式 (3)如果你用的是Mac电脑,当你直接用excel打开csv文件可能会显示乱码; 解决方法:在open()函数里加上参数'encoding='GBK' 代码二: start_floor = input('请输入起始楼层:') #end_floor = input('请输入终止楼层:') #确定每一单元有几层楼 start_floor_rooms = {} #创建字典,存放起始楼层所有户室的信息 floor_last_number = [] #创建列表,存放户室的尾号如['01','02','03'],后续楼层可复用
last_number = input('请输入起始楼层户室的尾号:(如01,02)')
floor_last_number.append(last_number) #将元素添加到存放户室尾号的列表里,如floor_last_number = ['01'] room_number = int(start_floor + last_number) #户室名为room_number,由楼层start_floor和尾号last_number组成,如'301' direction = int(input('请输入 %d 的朝向(南北朝向输入1,东西朝向输入2):' % room_number )) #输入中文比输入数字要麻烦许多,我们可以先用1和2代替 area = int(input('请输入 %d 的面积,单位 ㎡ :' % room_number)) start_floor_rooms[room_number] = [direction,area] # 户室号为键,朝向和面积组成的列表为值,添加到字典里,如start_floor_rooms = {301:[1,70]} print(start_floor_rooms)
---运行结果--- 请输入起始楼层:1 请输入起始楼层室的尾号:(如01,02):08 请输入108的朝向(南北朝向输入1,东西朝向输入2):2 请输入108的面积,单位平方米:32 {108:[2,32]} 代码3: for value in DictName.values(): # value的名字可以自行另取 # DictName是要遍历的字典的名称 # .values():是固定的用法 代码4: for k,v in DictName.items(): #遍历字典的键值对,k对应键,v对应值 #k,v 的名字可以自己取,DictName是字典名 15-19关常见问题解决办法 1、vscode打开拖入文本文件乱码问题: 答: 切记乱码问题,都是解码方式与编码方式不匹配原因导致,如果是直接拖拽文件到vscode乱码,那么就更换文件的编码:
选成utf-8就可以解决! 2、解码之后出现\ufeff
答:windows系统会出现的utf-8有无BOM的问题,这种情况encoding后面的解码方式更换成‘utf-8-sig’即可 3、课堂上这个为什么读取出来多遍难念的经?
课堂代码运行一遍就会写入一遍难念的经,有时候网络延迟问题或者多次点击写入,会导致多次写入 4、魔法学院的文档读入写入练习:
5、15关课后读取图片练习:
这里面因为图片都给大家内部嵌入了我们的在线编辑器系统里面,所以大家直接用相对路径即可~,注意读取模式,跟写入模式的选择 6、绝对路径,相对路径的区分使用办法~ 经常我们会报错找不到文件,或者17关二维码的额wrong picture。这两个问题我们都要首先查看下我们的地址,通常建议更换绝对路径 例如: 我要找到这个scores4,文本文档的绝对路径,右键鼠标点击属性
如图所示,我们现在可以开始拼合绝对路径,1+2中间用\分隔即可 得到: C:\Users\user\Desktop\scores(4).txt 因为编程里面 \ 如果不说明会被默认为转义字符,所以我们还要操作一下这个\ 方法一:全部改成 \\ 就是 :C:\\Users\\user\\Desktop\\scores(4).txt 方法二: 路径前面加上r ,默认让后面\ 都不转义:r'C:\Users\user\Desktop\scores(4).txt' 7、罗恩分数偏移量就检索不理解:
在我们测试出换行符长度是1之后,我们想要精准的区分分数部分 跟名字部分,因为姓名有两个字,跟三个字的。我们没办法精准定位,但是分数都是3位,于是采用倒数偏移量定位,确定名字的最后一位一定是-5偏移量,同时我们还可以确定名字第一位一定是0偏移量,所以可以准确区分。 8、古诗词默写:
9、倒计时代码不理解的地方: 倒计时的原理就是,利用time模块读取当前时间,通过遍历不断的一次次打印,因为改写参数不进行换行,重复打印然后退格,实现倒计时效果
10、如何使用vscode (强烈建议观看!) 纠结找不到图片的童鞋! 首先要在vscode文档区创建自己的文件夹:
点击箭头这个创建文件夹,如图我创建了演示文件夹 然后点击演示文件夹,点击箭头左边的图标,创建一个文件~
新建的文件都是文本文档,要想弄成代码可执行的文件,要另存修改格式为python
保存之后就可以输入自己的代码了~ 切记运行代码一定要在代码框右键python终端运行python文件
如果选错远了运行选定行,那么就会进入交互模式,也就是代码一行行执行,代码块结构运行会报错
当你的终端显示哪里出现三个大于号,就是进入了交互模式这时候在三个大于号后面输入: exit(),记住一定要英文格式然后回车,退出交互模式,重新正确运行 安装模块可以在终端框里输入命令进行安装:
然后回车即可下载~ 三百七十三 阅 目录 - 5、判断文件是不是被当成模块调用,来执行相关语句:
|