零基础入门学习Python(第2版)

小甲鱼

本书配套资源和网站支持

  • PPT课件请在清华大学出版社网站本书页面下载。

第1版前言

  • Life is short. You need Python。——Bruce Eckel
  • 有人说,完成相同的一个任务,使用汇编语言需要1000行代码,使用C语言需要500行,使用Java只需要100行,而使用Python,可能只要20行就可以了。
  • Python可以说是一门“万金油”语言,在Web应用开发、系统网络运维、科学与数字计算、3D游戏开发、图形界面开发、网络编程中都有它的身影。

第1章 就这么愉快地开始吧

  • 只有勇敢地割掉与时代发展不相符的瑕疵部分,才能缔造出真正的完美体验!
  • 安装Python非常容易,可以在它的官网找到最新的版本并下载,地址是http://www.python.org。

1.2 从IDLE启动Python

  • IDLE是一个Python shell,shell的意思就是“外壳”,是一个通过输入文本与程序交互的途径。
  • >>>提示符的含义是:Python已经准备好了,在等着你输入指令呢!

1.3 失败的尝试

  • 井号起到的作用是注释,也就是说,井号后边的内容是给人们看的,并不会被当作代码运行。

1.5 为什么会这样

  • print("I love python\n" * 3)
  • print("I love python\n" +3):

第2章 用Python设计第一个游戏

  • 选择File→New File命令(也可以直接使用Ctrl+N快捷键,在很多地方这个快捷键都是新建一个文件的意思)。
  • Tab按键的作用:(1)缩进。(2)IDLE会提供一些建议,例如,输入“pr TAB”会显示所有可能的命令供参考。
  • 好多编程语言都用大括号来表示循环、条件等的作用域,而在Python里是没有的。在Python中,只需要用适当的缩进来表示即可。

2.2 缩进

  • 缩进取而代之,它是Python的灵魂,缩进的严格要求使得Python的代码显得非常精简并且有层次
  • 如果在正确的位置输入冒号(:),IDLE会在下一行自动进行缩进。

2.3 BIF

  • BIF就是Built-in Functions,内置函数的意思。

第3章 成为高手前必须知道的一些基础知识

  • 当为一个值起名字的时候,它将会存储在内存中,我们把这块内存称为变量(variable)。
  • 变量为什么不叫“恒量”而叫“变量”?正是因为它是可变的!
  • 变量名可以包括字母、数字、下画线,但变量名不能以数字开头

3.2 字符串

  • 字符串也称为文本,文本和数字是截然不同的。
  • 要告诉Python你在创建一个字符串,就要在字符两边加上引号,可以是单引号或双引号,
  • 转义符号(\)对字符串中的引号进行转义,这样Pytho

3.3 原始字符串

  • 原始字符串的使用非常简单,只需要在字符串前边加一个英文字母r即可:

3.4 长字符串

  • 只需要使用三重引号字符串("""内容""")
  • 切记:编程中我们使用的所有标点符号都应该是英文的!

3.6 条件分支

  • 在Python中,用两个连续等号表示等于号,用单独一个等号表示赋值。那不等于呢?嗯,不等于这个有点特殊,用感叹号和一个等号搭配来表示(!=)。

3.7 初识循环

  • Python的逻辑操作符可以将任意表达式连接在一起,并得到一个布尔类型的值。布尔类型只有两个值:True和False,就是真与假。
  • 使用and逻辑操作符将左右两个条件串起来的时候,只有当两者同时成立,结果才能是True;否则均为False。

3.8 引入外援

  • random模块就是与生成随机数相关的模块,这个模块里边有一个函数为randint(),它会返回一个随机的整数

3.9 闲聊数据类型

  • Python的变量是没有类型的
  • 带了引号的,无论是双引号还是单引号或者是三引号,都是字符串;而不带引号的,就是数字。字符串相加称为拼接;数字相加就会得到两个数字的和:
  • 整型说白了就是平时所见的整数
  • Python区分整型和浮点型的唯一方式,就是看有没有小数点。
  • 布尔类型只有True和False两种情况
  • 布尔类型可以当作整数来对待,True相当于整型值1,False相当于整型值0
  • 把布尔类型当成1和0来参与运算这种做法是不妥的,容易引起代码的混乱。
  • int()的作用是将一个字符串或浮点数转换为一个整数:
  • 如果是浮点数转换为整数,Python会采取“截断”处理,就是把小数点后的数据直接砍掉,而不是四舍五入。
  • str()的作用是将一个数或任何其他类型转换成一个字符串
  • Python其实提供了一个函数,可以明确告诉我们变量的类型,这就是type()函数:
  • isinstance()函数有两个参数:第一个是待确定类型的数据;第二个是指定一个数据类型。

3.10 常用操作符

  • + - * / % ** //
  • 地板除法的概念是:计算结果取比商小的最大整型值(也就是舍弃小数,取整的意思)。
  • 使用地板除法,无论是整型还是浮点型,都将舍弃小数部分。
  • 百分号(%)表示求余数的意思
  • 先乘、除,后加、减,如有括号先运行括号里边的。
  • 双星号(**),也称为幂运算操作符
  • 幂运算操作符比其左侧的一元操作符优先级高,比其右侧的一元操作符优先级低。
  • 比较运算符包括: < <= > >= == !=
  • 逻辑操作符包括:and or not
  • or操作符只需要左边或者右边任意一边为真,结果都为真;只有当两边同时为假,结果才为假
  • not操作符是一个一元操作符,它的作用是得到一个和操作数相反的布尔类型的值:

第4章 了不起的分支和循环

  • Python是面向对象的编程

4.2 快速上手

  • 分支的含义是“只有符合条件,才会去做某事”;而循环则是“只要符合条件,就持续做某事”。

4.3 避免“悬挂else”问题

  • 缩进是Python的灵魂,缩进的严格要求使得Python的代码显得非常精简并且有层次,这种强制的规范使得代码必须被正确地对齐。

4.4 条件表达式(三元操作符)

  • 三元操作符语法: a = x if 条件 else y表示当条件为True的时候,a被赋值为x,否则被赋值为y。

4.5 断言

  • assert这个关键字翻译过来就是“断言”,当这个关键字后边的条件为假的时候,程序自动崩溃并抛出AssertionError异常。
  • 一般来说,可以用它在程序中置入检查点,当需要确保程序中的某个条件一定为真才能让程序正常工作的话,assert关键字就非常有用了。

4.6 while循环语句

  • 只要条件为真,while循环会一直重复执行一段代码,这段代码称为循环体。
  • 如果上面代码的循环体中缺少i += 1语句,循环将永远也不会退出(除非将程序强制关闭),也称为死循环

4.7 for循环语句

  • 所谓可迭代对象,就是指那些元素可以被单独提取出来的对象
  • range()是一个BIF函数,它可以为指定的整数生成一个数字序列(可迭代对象)

4.8 break语句

  • break语句的作用是终止当前循环,跳出循环体。

4.9 continue语句

  • continue语句,它的作用是跳出本轮循环并开始下一轮循环

4.10 else语句

  • while和for循环语句的后面也可以加上一个else语句,表示当条件不成立的时候执行的内容
  • break语句使得程序跳出循环,但却不会执行else中的内容。

第5章 列表、元组和字符串

  • 数组允许把一些相同类型的数据挨个儿摆在一起,然后通过下标进行索引。
  • 由于Python的变量没有数据类型,所以Python的“数组”可以同时存放不同类型的变量。
  • 创建一个列表非常简单,只需要使用中括号将数据包裹起来(数据之间用逗号分隔)就可以了。
  • type()函数用于返回指定参数的类型,list即列表的意思。
  • 可以看到这个列表里有整型、字符串、浮点型数据,甚至还可以包含另一个列表。
  • 添加元素到列表中,可以使用append()方法:
  • 因为append()并不是一个BIF,它是属于列表对象的一个方法。中间这个“.”,
  • 如果希望同时添加多个数据,可以使用extend()方法向列表末尾添加多个元素:
  • extend()事实上是使用一个列表来扩充另一个列表,所以它的参数是另一个列表。
  • insert()方法中代表位置的第一个参数还支持负数,表示与列表末尾的相对距离:
  • 通过索引值可以直接获取列表中的某个元素:
  • 使用len()函数获取该列表的长度(元素个数),再减1就是这个列表最后一个元素的索引值
  • random的choice()方法可以从一个非空的序列(如列表)中随机获取一个元素。
  • 从列表中删除元素,可以有三种方法实现:remove()、pop()和del。
  • pop()方法是将列表中的指定元素“弹”出来,也就是取出并删除该元素的意思,它的参数是一个索引值:
  • del语句在Python中的用法非常丰富,不仅可以用来删除列表中的某个(些)元素,还可以直接删除整个变量:
  • 如果省略了开始位置,Python会从0这个位置开始。同样道理,如果要得到从指定索引值到列表末尾的所有元素,把结束位置也省去即可。如果啥都没有,只有一个冒号,Python将返回整个列表的拷贝。
  • 列表切片并不会修改列表自身的组成结构和数据,它其实是为列表创建一个新的拷贝(副本)并返回。
  • 列表切片操作实际上还可以接受第三个参数,其代表的是步长,默认值为1。
  • 将步长设置为-1,相当于将整个列表翻转过来。
  • 同样会作用于原始列表的操作还有为切片后的列表赋值:
  • 当列表包含多个元素的时候,默认是从第一个元素开始比较,只要有一个PK赢了,就算整个列表赢了。
  • 乘号(*)也叫重复操作符
  • 成员关系操作符就是in和not in:
  • in和not in只能判断一个层次的成员关系
  • count()方法的作用是统计某个元素在列表中出现的次数
  • “懒”有时候确实是发明创新的原动力。

5.2 元组:戴上了“枷锁”的列表

  • 元组和列表的最大区别是:元组只可读,不可写。
  • 创建列表用的是中括号,而创建元组大部分时候使用的是小括号:
  • tuple即元组的意思。
  • 复制一个元组,通常可以使用切片来实现:
  • 逗号(,)才是关键,小括号只是起到补充的作用。
  • id()函数用于返回指定对象的唯一id值,这个id值可以理解为现实生活中的身份证,在同一生命周期中,Python确保每个对象的id值是唯一的。
  • 删除整个元组,只需要使用del语句:

5.3 字符串

  • 字符串与元组一样,都是属于“一言既出,驷马难追”的家伙。所以,一旦确定下来就不能再对它进行修改。如果非要这么做,仍然可以利用切片和拼接来实现:
  • 这种通过拼接旧字符串的各个部分组合得到新字符串的方式,并不是真正意义上的修改字符串。原来的那个旧的字符串其实还在,只不过我们将变量名指向了拼接后的新字符串。旧的字符串一旦失去了变量的引用,就会被Python的垃圾回收机制释放掉。
  • Python字符串的方法及含义
  • casefold()方法用于将字符串中所有的英文字母修改为小写:
  • 只要涉及字符串修改的方法,并不是修改原字符串,而是返回字符串修改后的一个拷贝。
  • find(sub[,start[,end]])或index(sub[,start[,end]])方法用于查找sub参数在字符串中第一次出现的位置,如果找到了,返回位置索引值;如果找不到,find()方法会返回-1,而index()方法会抛出异常(注:异常是可以被捕获并处理的错误)
  • split(sep=None, maxsplit=-1)方法用于拆分字符串:
  • 格式化字符串,就是按照统一的规格去输出一个字符串。
  • 但要注意的是,如果将位置参数和关键字参数综合在一起使用,那么位置参数必须在关键字参数之前,
  • Python格式化符号及含义令
  • 简单字符串连接时,直接使用加号(+),例如:full_name = prefix + name。 • 复杂的,尤其有格式化需求时,使用格式化操作符(%)进行格式化连接,例如:result = "result is %s:%d" % (name, score)。 • 当有大量字符串拼接,尤其发生在循环体内部时,使用字符串的join()方法无疑是最棒的,例如:result = "".join(iterator)。
  • 格式化操作符的辅助命令

5.4 序列

  • list()方法用于把一个可迭代对象转换为列表
  • 所谓迭代,是重复反馈过程的活动,其目的通常是为了接近并达到所需的目标或结果。每一次对过程的重复被称为一次“迭代”,而每一次迭代得到的结果会被用来作为下一次迭代的初始值
  • tuple()方法用于把一个可迭代对象转换为元组
  • str()方法用于把obj对象转换为字符串
  • len()方法前面已经使用过几次了,该方法用于返回sub参数的长度
  • max()方法用于返回序列或者参数集合中的最大值
  • 使用max()方法和min()方法都要保证序列或者参数的数据类型统一
  • sum()方法用于返回序列iterable的所有元素值的总和
  • 列表的内建方法sort()是实现列表原地排序;而sorted()是返回一个排序后的新列表。
  • 列表的内建方法是原地翻转,而reversed()是返回一个翻转后的迭代器对象。
  • enumerate()方法生成由二元组(二元组就是元素数量为2的元组)构成的一个迭代对象,每个二元组由可迭代参数的索引号及其对应的元素组成
  • zip()方法用于返回由各个可迭代参数共同组成的元组

第6章 函数

  • 在Python中创建一个函数用def关键字
  • 在函数名后面要加上一对小括号。这对小括号是必不可少的
  • 调用一个函数也非常简单,直接写出函数名加上小括号即可:
  • 括号里放的就是函数的参数
  • 参数就是使得函数可以实现个性化:
  • 奥卡姆剃刀原理:如无必要,勿增实体
  • 只需要在函数中使用关键字return,后面跟着的就是指定要返回的值。
  • 如果返回了多个值,Python默认是以元组的形式进行打包。
  • 也可以利用列表将多种类型的值打包到一块儿再返回。

6.2 灵活即强大

  • 形参指的是函数定义的过程中小括号里的参数,而实参则指的是函数在被调用的过程中传递进来的参数。
  • 函数的文档字符串可以通过特殊属性_ _doc_ _获取
  • 当想使用一个BIF却又不确定其用法的时候,可以通过help()函数来查看函数的文档:
  • 关键字参数其实就是在传入实参时明确指定形参的变量名,其特点就是参数之间不存在先后顺序
  • 位置参数必须在关键字参数的前面
  • 在定义函数的时候,位置参数必须在默认参数的前面,否则就会出错
  • Python就是把标志为收集参数的参数们打包成一个元组。
  • 如果在收集参数后面还需要指定其他参数,那么在调用函数的时候就应该使用关键参数来指定,否则Python就都会把实参都纳入到收集参数中。
  • 建议大家如果定义的函数中带有收集参数,那么可以将其他参数设置为默认参数
  • 星号(*)在形参中的作用是“打包”,而在实参中的作用则相反,起到“解包”的作用。
  • 两个星号的收集参数表示为将参数们打包成字典的形式

6.3 我的地盘听我的

  • 作用域是程序运行时变量可被访问的范围
  • 全局变量拥有更大的作用域,因此在函数中可以访问到它们
  • 如果在函数内部试图修改全局变量的值,那么Python会创建一个新的局部变量替代(名字与全局变量相同),但真正的全局变量是“不为所动”的,所以才有了上面的实现结果。
  • 仍然觉得有必要在函数内部去修改这个全局变量,那么可以使用global关键字来达到目的。
  • 内部函数整个作用域都在外部函数之内
  • 在嵌套函数中,内部函数可以引用外部函数的局部变量:
  • LEGB含义解释:• L-Local:函数内的名字空间。• E-Enclosing function locals:嵌套函数中外部函数的名字空间。• G-Global:函数定义所在模块的名字空间。• B-Builtin:Python内置模块的名字空间。那么变量的查找顺序依次就是L→E→G→B。
  • 简言之:就是在嵌套函数的环境下,内部函数引用了外部函数的局部变量),那么内部函数就被认为是闭包。
  • 如果在一个内部函数里(funY()就是这个内部函数)对在外部作用域(但不是在全局作用域)的变量进行引用(x就是被引用的变量,x在外部作用域funX()函数里面,但不在全局作用域里),则这个内部函数就是一个闭包。
  • 因为闭包的概念是由内部函数而来,所以不能在外部函数以外的地方对内部函数进行调用
  • 如果希望在内部函数里可以修改外部函数里的局部变量的值,可以使用nonlocal关键字告诉Python这不是一个局部变量,使用方式与global一样
  • 闭包概念的引入是为了尽可能地避免使用全局变量,闭包允许将函数与其所操作的某些数据(环境)关联起来,这样外部函数就为内部函数构成了一个封闭的环境。

6.4 函数式编程

  • 基本语法是使用冒号(:)分隔函数的参数及返回值:冒号的左边放置函数的参数,如果有多个参数,使用逗号(,)分隔即可;冒号右边是函数的返回值。
  • filter()这个内置函数有两个参数:第一个参数可以是一个函数也可以是None,如果是一个函数的话,则将第二个可迭代对象里的每一个元素作为函数的参数进行计算,把返回True的值筛选出来;如果第一个参数为None,则直接将第二个参数中为True的值筛选出来。

6.5 递归

  • 普通程序员用迭代,天才程序员用递归
  • 递归,从原理上来说就是函数调用自身的行为。
  • 压栈、弹栈、保存和恢复寄存器的栈操作,所以在这上面是非常消耗时间和空间的。
  • 所以在写递归代码的时候,千万要记住口诀:递归递归,归去来兮!

第7章 字典和集合

  • 字典是Python中唯一的映射类型
  • 映射类型区别于序列类型,序列类型以数组的形式存储,通过索引的方式来获取相应位置的值,一般索引值与对应位置存储的数据是毫无关系的。
  • 字典的使用非常简单,它有自己的标志性符号,就是用大括号({})定义。字典由“键”和“值”共同构成,每一对键值组合称为“项”。
  • 也可以使用dict()内置函数来创建字典:
  • 因为dict()函数的参数可以是一个序列(但不能是多个),所以要打包成一个元组(或列表)序列。
  • 这里要注意的是,键的位置不能加上表示字符串的引号,否则会报错:
  • 还有一种创建方法是直接给字典的键赋值,如果键已存在,则改写键对应的值;如果键不存在,则创建一个新的键并赋值
  • 有别于序列,字典是不支持拼接和重复操作的:
  • fromkeys()方法用于创建并返回一个新的字典,它有两个参数;第一个参数是字典的键;第二个参数是可选的,是传入键对应的值,如果不提供,那么默认是None。
  • keys()用于返回字典中的键,values()用于返回字典中所有的值,那么,items()当然就是返回字典中所有的键值对(也就是项)。
  • get()方法提供了更宽松的方式去访问字典项,当键不存在的时候,get()方法并不会报错,只是默默地返回了一个None,表示啥都没找到:
  • 如果希望找不到数据时返回指定的值,那么可以在第二个参数设置对应的默认返回值:
  • 如果不知道一个键是否在字典中,那么可以使用成员资格操作符(in或not in)来判断:
  • pop()是给定键弹出对应的值,而popitem()是弹出一个项,这两个比较容易理解:
  • setdefault()方法和get()方法有点相似,但是,setdefault()在字典中找不到相应的键时会自动添加:

7.2 集合:在我的世界里,你就是唯一

  • 在Python 3里,如果用大括号括起一堆数字但没有体现出映射关系,那么Python就会认为这堆数据是一个集合而不是映射。
  • 集合是无序的,也就是不能试图去索引集合中的某一个元素
  • 创建集合有两种方法:一种是直接把一堆元素用大括号({})括起来;另一种是用set()内置函数。

第8章 永久存储

  • close()方法用于关闭文件
  • 1个中文字符占用2字节的空间
  • readline()方法用于在文件中读取一整行,就是从文件指针的位置向后读取,直到遇到换行符(\n)结束:
  • 使用'w'模式写入文件,此前的文件内容会被全部删除
  • 如果要在原来的内容上追加,一定要使用'a'模式打开文件。

8.3 pickle:腌制一缸美味的泡菜

  • 它几乎可以把所有Python的对象都转化为二进制的形式存放,这个过程称为pickling,那么从二进制形式转换回对象的过程称为unpickling。
  • 利用pickle模块,不仅可以保存列表,事实上pickle还可以保存任何你能想象得到的东西。

9.2 try-except语句

  • try语句检测范围内一旦出现异常,剩下的语句将不会被执行。

9.3 try-finally语句

  • finally语句块中的内容就是确保无论如何都将被执行的内容。

9.5 丰富的else语句

  • 只要try语句块里没有出现任何异常,那么就会执行else语句块里的内容。

11.2 对象=属性+方法

  • 一个对象的特征称为“属性”,一个对象的行为称为“方法”
  • 创建一个对象,也叫类的实例化

11.3 面向对象编程

  • Python的self其实就相当于C++的this指针。
  • 在Python中定义私有变量只需要在变量名或函数名前加上“_ _”两个下画线,那么这个函数或变量就会成为私有的了:
  • 实际上在外部使用“_类名_ _变量名”即可访问两个下画线开头的私有变量了:

11.4 继承

  • 被继承的类称为基类、父类或超类;继承者称为子类,一个子类可以继承它的父类的任何属性和方法。
  • 如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性:

11.7 类、类对象和实例对象

  • 如果属性的名字与方法名相同,属性会覆盖方法

13.4 _ _name_ _='_ _main_ _'

  • 上面的代码确保只有单独运行p13_7.py时才会执行test()函数。