第1章 就这么愉快地开始吧
IDLE是一个python shell,shell 的意思就是“外壳”,从基本上说,就是一个通过输入文本与程序交互的途径。利用它,可以给操作系统下达命令。可以利用IDLE这个shell与python进行互动。
>>> 提示符
- 快捷键 Alt+N:复制上一条语句
- 快捷键 Alt+P:下一条语句
示例:
print("I love fishc.com")
print("I love fishc.com"*8)
print("well water" + "river")
print(5+3)
- 快捷键Ctrl+N:IDLE中新建一个文件
第2章 用python设计第一个游戏
缩进是python的灵魂,缩进的严格要求使得python的代码显得非常精简并且有层次。
Tab键,缩进
BIF(built-in-functions)内置函数
在IDLE中输入dir(__bulitins__),可以看到python提供的内置函数列表
。
help()这个BIF用于显示BIF的功能描述。
第3章 成为高手前必须知道的一些基础知识
3.1 变量
字符串的拼接:字符串+字符串
tips:
- 使用变量前,需要对其先赋值。
- 变量名可以包括字母、数字、下划线,但变量名不能以数字开头。
- 字母可以大写和小写,但大小写是不同的。
- 等号(=)是赋值的意思,左边是名字,右边是值。
- 变量的命名理论上可以取任何合法的名字,但作为一个优秀的程序员,尽量给变量取一个专业一点儿的名字。
3.2 字符串
字符串就是引号内的一切东西,字符串也叫做文本。
转义符号(\)
'let\'s go'
"let's go"
3.3 原始字符串
可以用反斜杠对自身进行转义。
原始字符串,只需要在字符串前加一个英文字母r即可。
tips:
- 使用字符串时,无论是否原始字符串,都不能以反斜杠作为结尾(反斜杠放在字符串的末尾表示该字符串还没有结束,换行继续的意思。)
3.4 长字符串
希望得到一个跨越多行的字符串:三重引号字符串
我爱鱼C,
正如我爱小甲鱼,
他那呱唧呱唧
呱唧呱唧
呱唧呱唧的声音
总萦绕在我的脑海,
久久不肯散去…
tips:
- 切记:编程中使用的标点符号都是英文的!
3.5 改进我们的小游戏
3.6 条件分支
python的条件分支语句:
if 条件:
条件为真(True)执行的操作
else:
条件为假(False)执行的操作
改进:
if guess == 8:
print("我操,你是小甲鱼心里的蛔虫吗?")
print("哼,猜中了也没有奖励!")
else:
if guess > 8:
print("哥,大了大了~")
else:
print("嘿,小了小了!!")
print("游戏结束,不玩啦~")
3.7 while循环
python的while循环
while 条件:
条件为真(True)执行的操作
改进
print("---------------我爱鱼C工作室-------------------")
temp = input("不妨猜测一下小甲鱼现在心里想的是哪个数字:")
guess = int(temp)
while guess != 8:
temp = input("哎呀,猜错了,请重新输入吧:")
guess = int(temp)
if guess == 8:
print("我操,你是小甲鱼心里的蛔虫吗?")
print("哼,猜中了也没有奖励!")
else:
if guess > 8:
print("哥,大了大了~")
else:
print("嘿,小了小了!!")
print("游戏结束,不玩啦~")
and逻辑操作符
python的逻辑操作符可以将任意表达式连接在一起,并得到一个布尔类型的值。布尔类型的值只有两个:True和False
3.8 引入外援
random模块,random.randint()函数,返回一个随机的整数。
import random
secret = random.randint(1,10)
print("---------------我爱鱼C工作室-------------------")
temp = input("不妨猜测一下小甲鱼现在心里想的是哪个数字:")
guess = int(temp)
while guess != secret:
temp = input("哎呀,猜错了,请重新输入吧:")
guess = int(temp)
if guess == secret:
print("我操,你是小甲鱼心里的蛔虫吗?")
print("哼,猜中了也没有奖励!")
else:
if guess > secret:
print("哥,大了大了~")
else:
print("嘿,小了小了!!")
print("游戏结束,不玩啦~")
3.9 闲聊数据类型
python的数值类型包含:整型、浮点型、布尔类型、复数类型等
3.9.1 整型
3.9.2 浮点型
E记法,科学计数法
1.5e4 1.5x10^4
3.9.3 布尔类型
布尔类型可以当做整数来对待,True相当于整型值1,False相当于整型值0,但把布尔类型当成1和0来参与运算这种做法是不妥的。
3.9.4 类型转换
int()、 float() 、str()
tips:
- 如果是浮点数转换为整数,python会采取“截断”处理,就是把小数点后的数据直接砍掉,注意不是四舍五入!
3.9.5 获取关于类型的信息
方式1:type()函数
方式2:isinstance()函数,有两个参数,一个是待确定类型的数据,一个是指定一个数据类型。isinstance会根据两个参数返回一个布尔类型的值,True表示类型一致,False表示类型不一致。
3.10 常用操作符
3.10.1 算术操作符
+ - * / %(取余) **(幂运算操作符) //(地板除法)
+= -= *= /=
3.10.2 优先级问题
3.10.3 比较操作符
< <= > >= == !=
3.10.4 逻辑操作符
and or not
第4章 了不起的分支和循环
其实,世界上根本没有最优秀的编程语言,只有最合适的语言,面对不同的环境和需求,就会有不同的编程工具去迎合。
4.1 分支与循环
打飞机框架.py
加载背景音乐
播放背景音乐(设置单曲循环)
我方飞机诞生
interval = 0
while True:
if 用户是否点击了关闭按钮:
退出程序
interval += 1
if interval == 50:
interval = 0
小飞机诞生
小飞机移动一个位置
屏幕刷新
if 用户鼠标产生移动:
我方飞机中心位置 = 用户鼠标位置
屏幕刷新
if 我方飞机与小飞机发生肢体冲突:
我方挂,播放撞机音乐
修改我方飞机图案
打印"game over"
停止背景音乐,最好淡出
4.2 课堂小练习
判断和循环,判断就是应不应该做某事,循环就是持续做某事。条件分支,就是判断,习惯用到的是if-else的搭配,循环就用while.
4.3 结果分析
判断会消耗CPU时间
要实现一个程序事实上并不难,但作为一个优秀的程序员,你必须要形成良好的编程思维。
4.4 python可以有效避免“悬挂else”
初学C语言的朋友很容易被以下代码欺骗
if (hi > 2)
if (hi > 7)
printf("好棒!好棒!")
else
printf("切~")
在这个例子中,虽然else是想和外层的if匹配,但事实上按照C语言的就近匹配原则这个else是属于内层if的。由于初学者的一不小心,就容易导致BUG的出现,这就是著名的悬挂else。
python的缩进使用强制规定
4.5 条件表达式(三元操作符)
“多少元”操作符的意思是这个操作符有多少个操作数。赋值操作符“=”是二元操作符,所以它有左边和右边两个操作数,“-”是一元操作符,表示负号,只有一个操作数。
if x < y:
small = x
else:
small = y
三元操作符语法
a = x if x < y else y
改进
small = x if x < y else y
4.6 断言
断言(assert)这个关键字称为“断言”,当这个关键字后边的条件为假的时候,程序自动崩溃并抛出AssertionError异常。
什么情况下需要这样的代码呢?当我们在测试程序的时候与其让错误的条件导致程序今后莫名其妙地崩溃,不如在错误条件出现的那一瞬间实现“自爆”。
一般来说,可以用它在程序中置入检查点,当需要确保程序中的某个条件一定为真才能让程序正常工作时,assert关键字就非常有用了。
4.7 while循环语句
python的while循环跟if条件分支类似,在条件为真的情况下,执行一段代码,不同的是,只要条件为真,while循环会一直重复执行那段代码,把这段代码称为循环体。
while条件:
循环体
4.8 for循环语言
python的计数器循环,for循环。
语法:
for 目标 in 表达式:
循环体
4.9 range()
语法:
range([start,]stop[,step=1])
range()可以说是跟for循环最合适做搭档的小伙伴。
4.10 break语句
break语句的作用是终止当前循环,跳出循环体。
bingo = "小甲鱼是帅哥"
answer = input("请输入小甲鱼最想听的一句话:")
while True:
if answer == bingo:
break
answer = input("抱歉,错了,请重新输入(答案正确才能退出游戏):")
print("哎呦,帅哦~")
print("您真是小甲鱼肚子里的蛔虫啊~")
4.11 continue语句
continue语句的作用是终止本轮循环并开始下一轮循环(注意:在开始下一轮循环之前,会先测试循环条件)。
第5章 列表、元组和字符串
5.1 列表:一个“打了激素”的数组
5.1.1 创建列表
number = [1,2,3,4,5,6]
member = ['小甲鱼','小布丁','黑夜','迷途','意境']
mix = [1,"小甲鱼",3.14,[1,2,3]]
empty = []
5.1.2 向列表添加元素
append()方法不是一个BIF,它是属于列表对象的一个方法。
属于对象的函数称为方法。
方法1:append()方法
方法2:extend()方法,extend()方法事实上使用一个列表来拓展另一个列表,所以它的参数应该是一个列表。
方法3:insert()方法
tips:
- 凡是顺序索引,python均从0开始,同时这也是大多数编程语言约定俗成的规范。
5.1.3 从列表中获取元素
通过元素的索引值(index)从列表中获取单个元素,注意,列表索引值是从0开始的。
5.1.4 从列表删除元素
方法1:remove(),参数是元素的名字
方法2:del,del是一个语句,不是一个列表的方法,所以不必在它后边加上小括号()。如果想删除整个列表,可以直接用del加列表名删除。
方法3:pop(),pop()方法默认是弹出列表中的最后一个元素。当为它加上一个索引值作为参数的时候,它会弹出这个索引值对应的元素。
5.1.5 列表分片
列表分片就是建立原列表的一个拷贝(或者说副本),所以如果你想对列表做出某些修改,但同时还想保持原来的那个列表,就直接使用分片的方法。
5.1.6 列表分片的进阶玩法
5.1.7 一些常用操作符
当列表中包含多个元素时,默认从第一个元素开始比较,只要有1个PK赢了,就算整个列表赢了。字符串比较同理(字符串比较的是第一个字符对应的ASCII码值的大小)。
加号(+)也叫连接操作符,可把多个列表对象合并在一起,相当于extend()方法实现的效果,一般情况下建议大家使用extend()方法来扩展列表,这样显得更为规范和专业。另外,连接操作符并不能实现列表添加新元素的操作。
乘号(*)也叫重复操作符
成员关系操作符 in 、not in
5.1.8 列表的小伙伴们
count()方法的作用是计算它的参数在列表中出现的次数
index()方法返回它的参数在列表中的位置
reverse()方法的作用是将整个列表原地翻转,改变了列表
sort()方法用指定的方式对列表的成员进行排序,默认不需要参数,从小到大排序。sort(func,key,reverse)
sort(reverse= True)反向排序
5.1.9 关于分片“拷贝”概念的补充
- END - 2019/4/20 23:18
5.2 元组:戴上了枷锁的列表
元组和列表最大的区别就是你可以任意修改列表中的元素,可以任意插入或者删除一个元素,而对元组是不行的,元组是不可改变的。
5.2.1 创建和访问一个元组
创建列表用的是中括号[],而创建元组大部分时候用的是小括号()(注意:这里说的是大部分)。
列表的标志性符号是中括号([ ]),那么元组的标志性符号是什么?
小括号呀 ×
就算没有小括号,temp还是元组类型,所以逗号(,)才是关键,小括号只是起到补充的作用。如果想要创建一个空元组,直接使用小括号即可。
tips
-
如果要创建的元组中只有一个元素,请在它后边加上一个逗号(,),这样可以明确告诉python你要的是一个元组。
5.2.2 更新和删除元组
如何更新一个字符串的?通过拷贝现有的字符串片段构造一个新的字符串的方式解决,对元组也是使用同样的方法。
通过分片的方法让元组拆分成两部分,然后使用连接操作符(+)合并成一个新元组,最后将原来的变量名指向连接好的新元组。逗号是必须的,小括号也是必须的。
要删除整个元组,只要使用del语句即可显式地删除一个元组。但日常使用中,很少使用del去删除整个元组,因为python的回收机制会在这个元组不再被使用到的时候自动删除。
5.3 字符串
tips:
- 通过拼接旧字符串的各个部分得到新字符串的方式并不是真正意义上的改变了原始字符串,原来的那个字符串还在,只是将变量指向了新的字符串(旧的字符串一旦失去了变量的引用,就会被python的垃圾回收机制释放掉)。
5.3.1 各种内置方法
字符串的方法及注释https://fishc.com.cn/thread-38992-1-1.html
5.3.2 格式化
格式化字符串就是按照统一的规格去输出一个字符串。
1.format()
format()方法接受位置参数和关键字参数,二者均传递到一个叫做replacement字段,而这个replacement字段在字符串内由大括号({})表示。
tips:
-
将位置参数和关键字参数综合在一起使用,那么位置参数必须在关键字参数之前,否则会出错。
位置参数“不打印”没有被输出,这是因为{0}的特殊功能被外层的大括号{}剥夺,因此没有字段可以输出。
在替换域中,冒号表示格式化符号的开始,“.1”的意思是四舍五入到保留1位小数点,f的意思是浮点数。
2.格式化操作符:%
字符串独享的一个操作符:%
当%左右均为数字的时候,它表示求余数的操作;但当它出现在字符中的时候,它表示的是格式化操作符。
3.python的转义字符集含义
5.4 序列
列表、元组和字符串的共同点:
- 都可以通过索引得到每一个元素
- 默认索引值总是从0开始
- 可以通过分片的方法得到一个范围内的元素的集合
- 有很多共同的操作符(重复操作符、拼接操作符、成员关系操作符)
统称为:序列
1. list([iterable])
list()方法用于把一个可迭代对象转换为列表。
迭代,就是重复反馈过程的活动,其目的通常是为了接近并达到所需的目标或结果。每一次对过程的重复过程被称为一次“迭代”,而每一次迭代得到的结果会被用来作为下一次迭代的初始值……,就目前来说,迭代就是一个for循环。
2. tuple([iterable])
tuple()方法用于把一个可迭代对象转换为元组,具体用法与list()一样。
3. str(obj)
str()方法吧obj对象转换为字符串。
4. len(sub)
len()方法用于返回sub参数的长度。
5. max(```)
max()方法用于返回序列或参数集合中的最大值。
6. min(```)
min()方法用于返回序列或参数集合中的最小值。
tips:
- 使用max()和min()方法都要保证序列或参数的数据类型统一,否则会出错。
7. sum(iterable[,start])
sum()方法用于返回序列iterable的综合,可选参数strat,如果设置该参数,表示从该值开始加起,默认值是0.
8. sorted(iterable,key=None,reverse=False)
sorted()方法用于返回一个排序的列表,列表的内置方法sort()是实现列表原地排序;而sorted()是返回一个排序后的新列表。
9. reversed(sequence)
reversed()方法用于返回逆向迭代序列的值。实现效果跟列表的内置方法reverse()一致,区别是列表的内置方法是原地翻转,而reversed()是返回一个翻转后的迭代器对象。
10. enumerate(iterable)
enumerate()方法生成由二元组(二元组就是元素数量为二的元组)构成的一个迭代对象,每个二元组是由可迭代参数的索引号及其对应的元素组成的。
11. zip(iter1[,iter2[```]])
zip()方法用于返回由各个可迭代参数共同组成的元组。
第6章 函数
6.1 python的乐高积木
优秀的东西永远是经典的,而经典的东西永远是简单的。要能够把复杂的东西简单化才能成为经典。
为了使得程序的代码更为简单,需要把程序分解成较小的组成部分。这里通过三种方式来实现:函数、对象和模块。
6.1.1 创建和调用函数
函数就是把代码打包成不同形状的乐高积木,以便可以发挥想象力进行随意拼装和反复使用。
在python中创建一个函数用def关键字,在函数名后边要加上一对小括号,必不可少。
6.1.2 函数的参数
使用多个参数,只需要用逗号隔开即可。
6.1.3 函数的返回值
6.2 灵活即强大
灵活表现为多变
6.2.1 形参和实参
形式参数(parameter)和实际参数(argument)
6.2.2 函数文档
给函数写文档是为了让别人可以更好地理解你的函数。
- 函数的文档字符串可以通过特殊属性_doc_获取。
- 想用一个函数却不确定其用法的时候,会通过help()函数来查看函数的文档。
6.2.3 关键字函数
6.2.4 默认参数
默认参数是在定义的时候赋予了默认值的参数。
6.2.5 收集参数
也叫可变参数,在参数前边加上星号(*)即可。
tips:
- python把标志为收集参数的参数们打包成一个元组。
- 如果在收集参数后边还需要指定其他参数,在调用函数的时候就应该使用关键字参数来指定,否则python就会把你的实参都列入收集参数的范畴。
-
如果你的参数中带有收集参数,可将其他参数设置为默认参数。
6.3 我的地盘听我的
6.3.1 函数和过程
在很多编程语言中,函数和过程其实是分开的。一把认为函数(function)是有返回值的,而过程(procedure)是简单、特殊并且没有返回值的。
python严格来说只有函数,没有过程。python的所有函数都有返回值。
6.3.2 再谈谈返回值
6.3.3 函数变量的作用域
在函数里边定义的参数以及变量,都称为局部变量。出了这个函数,这些变量都是无效的。事实上 的原理是,python在运行函数的时候,利用栈进行存储,当执行完该函数后,函数中的所有数据都会被自动删除。所以在函数外边是无法访问函数内部的局部变量的。
全局变量
如果在函数内部试图修改全局变量,那么python会创建一个新的局部变量替代,但真正的全局变量时不变的。
可以在函数内部访问全局变量。
6.4 内嵌函数和闭包
6.4.1 global关键字
全局变量的作用域是整个模块(整个代码段),也就是代码段内所有的函数内部都可以访问到全局变量。但在函数内部仅仅去访问全局变量就好,不要试图去修改它。
python会使用屏蔽的方式“保护”全局变量:一旦函数内部试图修改全局变量,python就会在函数内部自动创建一个名字一模一样的局部变量,这样修改的结果只会修改到局部变量,而不会影响到全局变量。
6.4.2 内嵌函数
python的函数定义是可以嵌套的,也就是允许在函数内部创建另一个函数,这种函数叫做内嵌函数或内部函数。
6.4.3 闭包(closure)
闭包是函数式编程的一个重要的语法结构,函数式编程是一种编程范式。
python中的闭包从表现形式上定义为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。
如果在一个内部函数里(FunY就是这个内部函数)对外部作用域(但不是在全局作用域)的变量进行引用(x就是被引用的变量,x在外部作用域FunX函数里,但不在全局作用域里),则这个内部函数(FunY)就是一个闭包。
- 闭包的概念是由内部函数而来的,所以不能在外部函数以外的地方对内部函数及进行调用。
- 在闭包中,外部函数的局部变量对应内部函数的局部变量,事实上相当于之前将的全局变量跟局部变量的对应关系,在内部函数中,你只能对外部函数的局部变量进行访问,但不能进行修改。
python认为在内部函数的x是局部变量的时候,外部函数的x就被屏蔽了。
通过容器类型来存放,因为容器类型不是存放在栈里,所以不会被“屏蔽”掉。字符串、列表、元组,这些什么都可以往里放的就是容器类型。
如果希望在内部函数里可以修改外部函数里的局部变量的值,使用关键字nonlocal。
6.5 lambda表达式
python的lambda表达式语法非常精简,基本语法是在冒号(:)左边放原函数的参数,可以有多个参数,用逗号(,)隔开即可;冒号右边是返回值。
lambda语句时间上是返回一个函数对象,如果要对它进行使用,只需要进行简单的赋值操作即可。
介绍两个BIF:filter()和map()
1. filter()
filter有两个参数。第一参数可以是函数也可以是None,如果是一个函数的话,则将第二个可迭代数据里的每一个元素作为函数的参数进行计算,把返回True的值筛选出来;如果第一个参数是None,则直接将第二个参数中为True的值筛选出来。
2.map()
在编程领域,map()一般做“映射”来解释。map()也有两个参数,仍然是一个函数和一个可迭代序列,将序列中的每一个元素作为函数的参数进行运算加工,直到可迭代序列每个元素都加工完毕,返回所有加工后的元素构成的新序列。
6.6 递归
6.6.1 递归是“神马”
递归是算法的范畴。
python3,对递归的深度默认限制是100层。
6.6.2 写一个求阶乘的函数
6.6.3 这帮小兔崽子
6.6.4 汉诺塔
第7章 字典和集合
7.1 字典:当索引不好用时
键(key) 值(value)
字典是python中唯一的映射类型,映射是数学上的一个术语。
7.1.1 创建和访问字典
字典的标志性符号是大括号{},字典由多个键和值共同构成,每一对键值组合成为项。
字典跟序列不同,序列讲究顺序,字典讲究映射,不讲顺序。
要声明一个空字典,直接用个大括号即可。
可以用dict()来创建字典
注意键的位置不能加上字符串的引号,否则会报错。
- END - 2019/4/21 20:55
7.1.2 各种内置方法
字典是python中唯一的映射类型,字典不是序列。
1. fromkeys()
fromkeys()方法用于创建并返回一个新的字典,它有两个参数:第一个参数是字典的键;第二个参数是可选的,是传入键对应的值。如果不提供,默认是None。
2. keys()、values()和items()
访问字典的方法有keys()、values()和items().
- keys()用于返回字典中的键;
- values()用于返回字典中的所有值;
- items()用于返回字典中所有的键值对(也就是项)。
3. get()
get()方法提供了更宽松的方式去访问字典项,当键不存在的时候,get()方法并不会报错,知识默默地返回了一个None。
4. copy()
copy()方法是复制字典。浅拷贝。浅拷贝和直接复制不一样。
5. pop()和popitem()
pop()是给定键弹出对应的值,而popitem()是弹出一个项。
setdefault()方法
和get()方法类似,但setdefault()在字典中找不到相应的键时会自动添加。
6. update()
update()可以用来更新字典。
7.2 集合:在我的世界里,你就是唯一
集合在python中几乎起到的所有作用就是:唯一。
集合是无序的,你不能试图去索引集合中的某一个元素。
7.2.1 创建集合
创建集合的2种方法:1)直接把一堆元素用大括号{}括起来;2)用set()
去掉列表中重复的元素
7.2.2 访问集合
- 由于集合中的元素时无序的,所以并不能像序列那样用下标来进行访问,但是可以使用迭代把集合中数据一个个读取出来
- 可以用in和not in判断一个元素是否在集合中已经存在
-
使用add()方法可以为集合添加元素,使用remove()方法可以删除集合中已知的元素。
7.2.3 不可变集合
使用frozenset()函数定义不可变集合。
第8章 永久存储
编写代码的时候,操作系统为了更快的做出响应,把所有当前的数据都放在内存中,因为内存和CPU数据传输的速度要比在硬盘和CPU之间传输的速度快很多。但内存有一个天生的不足,一旦断电就没戏,所以,请随时使用快捷键Ctrl+C
8.1.1 打开文件
使用open()成功打开一个文件之后,它会返回一个文件对象,拿到这个文件对象,就可以读取或修改这个文件。
8.1.2 文件对象的方法
- END - 2019/4/22 23:24
8.1.3 文件的关闭
python拥有垃圾回收机制,会在文件对象的引用计数降至0的时候自动关闭文件,所以在python编程李,如果忘记关闭文件并不会造成内存泄漏那么危险的结果。
8.1.4 文件的读取和定位
文件的读取方法很多,可以使用文件对象的read()和readline()方法,也可直接list(f)或者直接使用迭代来读取。read()是按字节为单位读取,如果不设置参数,那么会全部读取出来,文件指针指向文件末尾。tell()方法可以告诉你当前指针的位置。
文件指针可以认为它是一个“书签”,起到定位的作用。使用seek()方法可以调整文件指针的位置。
seek(offset,from)方法有两个参数,表示从from(0代表文件起始位置,1代表当前位置,2代表文件末尾)偏移offset字节。
将文件指针设置到文件起始位置,使用seek(0,0)。
readline()方法用于在文件中读取一整行,就是从文件指针的位置向后读取,直到遇到换行符(\n)结束。
文件对象本身是支持迭代的,直接使用for语句把内容迭代读取即可。
8.1.5 文件的写入
如果要写入文件,请确保之前的打开模式有‘w’或'a',否则会出错。
使用'w'模式写入文件,此前的文件内容会被全部删除。
如果要在原来的内容上追加,一定要使用'a'模式打开文件。
8.1.6 一个任务
tes_1.py
f = open(r'C:\Users\22254\Desktop\零基础入门学习python-work\record2.txt')
boy = []
girl = []
count = 1
for each_line in f:
if each_line[:6] != '======':
# 我们这里进行字符串分隔操作
(role,line_spoken) = each_line.split(':',1)
if role == '小甲鱼':
boy.append(line_spoken)
if role == '小客服':
girl.append(line_spoken)
else:
# 文件的分别保存操作
file_name_boy = 'boy_' + str(count) + '.txt'
file_name_girl = 'girl_' + str(count) + '.txt'
boy_file = open(file_name_boy,'w')
girl_file = open(file_name_girl,'w')
boy_file.writelines(boy)
girl_file.writelines(girl)
boy_file.close()
girl_file.close()
boy = []
girl = []
count += 1
file_name_boy = 'boy_' + str(count) + '.txt'
file_name_girl = 'girl_' + str(count) + '.txt'
boy_file = open(file_name_boy,'w')
girl_file = open(file_name_girl,'w')
boy_file.writelines(boy)
girl_file.writelines(girl)
boy_file.close()
girl_file.close()
f.close()
tes_2.py
def save_file(boy,girl,count):
file_name_boy = 'boy_' + str(count) + '.txt'
file_name_girl = 'girl_' + str(count) + '.txt'
boy_file = open(file_name_boy,'w')
girl_file = open(file_name_girl,'w')
boy_file.writelines(boy)
girl_file.writelines(girl)
boy_file.close()
girl_file.close()
def split_file(file_name):
f = open(r'C:\Users\22254\Desktop\零基础入门学习python-work\record2.txt')
boy = []
girl = []
count = 1
for each_line in f:
if each_line[:6] != '======':
# 我们这里进行字符串分隔操作
(role,line_spoken) = each_line.split(':',1)
if role == '小甲鱼':
boy.append(line_spoken)
if role == '小客服':
girl.append(line_spoken)
else:
# 文件的分别保存操作
save_file(boy,girl,count)
boy = []
girl = []
count += 1
save_file(boy,girl,count)
f.close()
split_file('record2.txt')
8.2 文件系统:介绍一个高大上的东西
模块是一个包含所有你定义的函数和变量的文件,后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。
OS模块(operating system),操作系统。OS模块高大上,是因为对于文件系统的访问,python一般是通过OS模块来实现的。
常用的操作系统windows/Mac OS/Linux/UNIXdeng ,这些操作系统底层对于文件系统的访问工作原理是不同的,因此你可能就要针对不同的系统来考虑使用哪些文件系统模块。
但python是跨平台的语言,同样的源代码在不同的操作系统不需要修改就可以同样实现。有了OS模块,不需要关心什么操作系统下使用什么模块,OS模块会帮你选择正确的模块并调用。
1. getcwd()
有些情况需要获得应用程序当前的工作目录(比如要保存临时文件)
2.chdir(path)
用chdir()函数可以改变当前工作目录
3. listdir(path='.')
列举指定目录中的文件名(‘.’表示根目录,‘..’表示上一级目录)
8.3 pickle:腌制一缸美味的泡菜
pickle模块几乎可以把所有python的对象都转化为二进制的形式存放,这个过程称为pickling,那么从二进制形式转换回对象的过程称为unpickling.
使用dump方法来保存数据。
第9章 异常处理
9.1 你不可能总是对的
作为一个合格的程序员,在编程的时候一定要意识到一点,就是永远不要相信你的用户,要把他们想象成熊孩子,把他们想象成黑客,他们总是想要搞掉你的程序,这样你写出来的程序自然就会更加安全和稳定。
程序出现逻辑错误或用户输入不合法都会引发异常,但这些异常并不是致命的,不会导致程序崩溃死掉。可以利用python提供的异常处理机制,在异常出现的时候及时捕获,并从内部自我消化掉。
1. AssertionError:断言语句(assert)失败
当Assert这个关键字后边的条件为假的时候,程序将停止并抛出AssertionError异常。assert语句一般是在测试程序的时候用于在代码中置入检查点。
2. AttributeError:尝试访问未知的对象属性
当试图访问的对象属性不存在时抛出的异常
3. IndexError:索引超出序列的范围
4. KeyError:字典中查找一个不存在的关键字
建议使用dict.get()方法
5. NameError:尝试访问一个不存在的变量
6. OSError:操作系统产生的异常
OSError是操作系统产生的异常,像打开一个不存在的文件会引发FileNotFoundError(是OSError的子类)。
7. SyntaxError:python的语法错误
8. TypeError:不同类型间的无效操作
9. ZeroDivisionError:除数为零
异常捕获可以使用try语句来实现,任何出现try语句范围内的异常都会被及时捕获到。try语句有两种实现方式:try-except; try-finally
9.2 try-except语句
使用as把具体的错误信息打印出来。
9.2.1 针对不同异常设置多个except
9.2.2 对多个异常统一处理
9.2.3 捕获所有异常
…
except:
print('出错啦')
…
不建议,会隐藏所有程序员未想到并且未做好准备的错误,例如当用户输入Ctrl+C试图终止程序,却被解释为KeyboardInterrupt异常。
注意:try语句检测范围一旦出现异常,剩下的语句将不会被执行。
9.3 try-finally语句
如果try语句块中没有任何运行时错误,会跳过except语句块执行finally语句块的内容。如果出现异常,则会先执行except语句块的内容再执行finally语句块的内容。总之,finally语句块中的内容就是确保无论如何都将被执行的内容。
9.4 raise语句
9.5 丰富的else语句
1. 要么怎样,要么不怎样
典型的if-else语句
2. 干完了能怎样,干不完就别想怎样
else可以跟for while循环语句配合使用,但else语句块只在循环完成后执行,也就是说,如果循环中使用break语句跳出循环,那么else里边的内容就不会被执行了。
3. 没有问题?那就干吧
else语句还能跟异常处理进行搭配。只要try语句块没有出现异常,就会执行else语句块中的内容。
9.6 简洁的with语句
with会自动帮你关闭文件。
第10章 图形用户界面入门
10.1 导入EasyGui
10.2 使用EasyGui
10.3 修改默认设置
《EasyGui学习文档》https://fishc.com.cn/forum.php?mod=viewthread&tid=46069&extra=page%3D1%26filter%3Dtypeid%26typeid%3D403
第11章 类和对象
11.1 给大家介绍对象
封装,把乱七八糟的数据扔进列表里,这是一种封装,是数据层面的封装;把常用的代码段打包成一个函数,这也是一种封装,是语句层面的封装。对象,也是一种封装的思想。对象的来源是模拟真实世界,把数据和代码都封装在一起了。
11.2 对象 = 属性 + 方法
一个对象的特征称为属性(特征的描述称为属性,在代码层面来看其实就是变量),一个对象的行为称为方法(方法其实就是函数,通过调用这些函数来完成某些工作)。
定义了对象的特征(属性)和行为(方法),但还不是一个完整的对象,将定义的这些称为类(Class)。需要使用类来创建一个真正的对象,这个对象就叫做这个类的一个实例,也叫做实例对象。
创建一个对象,叫做类的实例化。
11.3 面向对象编程
多态就是不同对象对同一方法响应不同的行动
11.3.1 self是什么
python的self相当于C++的this指针。
把类比作是图纸,由类实例化后的对象才是真正可以住人的房子。根据一张图纸可以设计除成千上万的房子,都长得差不多,但是他们都有不同的主人。每个人都只能回到自己注的房子,所以self相当于每个房子的门牌号,有了self,就可以轻松找到自己的房子。
python的self参数同理,由同一个类可以生成无数对象,当一个对象的方法被调用的时候,对象会将自身的引用作为第一个参数传给该方法,那么python就知道需要操作哪个对象的方法了。
11.3.2 你听说过python的魔法方法吗
特殊方法:_init()称为构造方法,_init()方法的魔力体现在只要实例化一个对象,这个方法就会在对象被创建时自动调用。实例化对象时是可以传入参数的,这些参数会自动传入_init_()方法中,可以通过重写这个方法来自定义对象的初始化操作。
11.3.3 公有和私有
默认上对象的属性和方法都是公开的,可以通过点操作符(.)进行访问。
为了实现类似私有变量的特征,python内部采用了一种叫name mangling(名字改编)的技术,在python中定义私有变量只需要在变量名或函数名前加上“__”两个下划线,那么这个函数或变量就会变成私有的了。
python动了手脚,把双下横线开头的变量进行了改名。实际上在外部使用“_类名__变量名”即可访问双下横线开头的私有变量。
注:python目前的私有机制其实是伪私有的,python的类没有权限控制的,所有变量都是可以被外部调用的。
11.4 继承
语法:
class 类名(被继承的类):
被继承的类称为基类、父类或超类;继承者称为子类,一个子类可以继承它的父类的任何属性和方法。
注意:如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性。
异常:Shark对象没有x属性。原因:在Shark类中,重写了魔法方法__init__,但新的__init__方法里面没有初始化鲨鱼的x坐标和y坐标,因此调用move方法就会出错。解决这个问题应该在鲨鱼类中重写__init__方法的时候先调用基类Fish中的__init__方法。
- 调用未绑定的父类方法。
- 使用super函数。
11.4.1 调用未绑定的父类方法
Fish.__init__(self)
注意:这个self并不是父类Fish的实例对象,而是子类Shark的实例对象,所以说这里未绑定的是指并不需要绑定父类的实例对象,使用子类的实例对象代替即可。
11.4.2 使用super函数
super()函数能够帮我自动找到基类的方法,而且还为我们传入了self参数。
super函数的超级之处在于你不需要明确给出任何基类的名字,它会自动帮你找出所有基类以及对应的方法。由于你不用给出基类的名字,这就意味着如果需要改变类继承关系,只要改变class语句里的父类即可,而不必在大量代码中去修改所有被继承的方法。
11.5 多重继承
语法:
class 类名(父类1,父类2,父类3,…)
多重继承很容易导致代码混乱,所以当不确定是否真的必须使用多重继承的时候,请尽量避免使用它,因为有些时候会出现不可预见的BUG。
11.6 组合
组合就是把类的实例化放在一个新类里面