学Python的笔记(在网上自学的总结)

目录

壹、简单入门(安装Python就不说啦,仅Windows系统)

1、Python的交互模式:Python大小写敏感

2、练习1:

3、基础的函数

(1)让Python打印出指定的文字,用print()函数

贰、尝试第一个Python程序

1、练习:

2、Python代码运行助手

3、输入和输出

(1)输出:print()

(2)输入input() ,让用户向电脑输入字符

叁 Python基础

1、数据类型 和 变量

①整数(也包括负整数)---int()

②浮点数(也就是小数)---float()

③字符串------str()

④布尔值----True 和 False

⑤空值-----None

⑥变量

⑦常量---除法(/ 或者 //)---求余(%)

2、字符串和编码

①字符编码

②字符串 str 

③格式化 %

3、使用 list[] 和 tuple ()

① list:有序集合 [ ]-----len()获得集合或元组中元素的个数

②tuple():有序列表的元组(和 list 很相似)

4、条件判断---- if

5、循环(Python的循环有两种)------① for ... in ------② while x

① for x  in list / tuple : -------range()

②while x :

③break--------通常配合 if 使用

④continue----通常配合 if 使用

小结:

6、使用dict{} 和 set ()----不是很明白怎么用,先过一遍,再回来深入学习

肆、函数-------卡住了,不是很明白怎么用,先过一遍,再回来深入学习

1、调用函数

(1)调用函数

(2)数据类型转换 int()

2、定义函数

(1)定义函数--- def() 语句---

(2)空函数--- pass语句

(3)参数检查

(4)返回多个值

3、函数的参数

4、递归函数 fact() ---------

伍、高效特性

1、切片(Slice)

2、迭代----(for...in)

3、列表生成式

4、生成器 generator------generator也是可迭代对象

5、迭代器

陆、函数式编程

1、高阶函数(higher-order function):一个函数可以接受另一个函数作为参数

① map / reduce

② filter() ---- 用于过滤序列---- 关键在于正确实现一个 “ 筛选” 函数----- filter的作用是从一个序列中筛选出符合条件的元素

③ sorted 

2、返回函数

3、匿名函数----lambda()

4、装饰器-----decorator(),在代码运行期间动态增加功能的方式

5、偏函数----partial()

柒、模块

1、使用模块

2、安装第三方模块

捌、面向对象编程

1、类(class)和实例(Instance)

2、访问限制

3、继承和多态

4、获取对象信息

5、实例属性和类属性

玖、面向高级对象编程

1、使用__slots__

2、使用 @property

3、多重继承

4、定制类

__str__

__repr__ 返回一个好看的字符串

__iter__ ----返回一个迭代对象

__getitem__

__getattr__

__call__ --定义一个__call__()方法,就可以直接对实例进行调用

5、使用枚举类-----Enum类

6、使用元类

拾、错误、调试和测试

错误处理

调试

单元测试

文档测试

 

拾、IO编程(本章都是同步IO)

文件读写

StringIO 和 BytesIO

操作文件和目录

环境变量

操作文件和目录

小结

序列化(pickling)

JSON

11、进程和线程

多进程

多线程

ThreadLocal

进程 vs 线程

12、正则表达式

13、常用内建模块

detatime

小结

collections

namedtuple

deque

defaultdict

OrderedDict

ChainMap

Counter

base64

struct

hashlib(摘要算法)

hmac

itertools====提供了用于操作迭代对象的函数

contextlib

urllib=======利用程序去执行各种HTTP请求

XML

HTMLParse

14、常用第三方模块

Pillow

requests-------获取URL资源

chardet------检测编码

psutil-------实现系统监控

15、virtualenv-----隔离的python运行环境

16、图形界面

Tkinter

第一个GUI程序

海龟绘图

17、网络编程

TCP/IP简介

TCP编程

UDP编程

18、电子邮件

SMTP发送邮件-------发送邮件的协议

POP3收取邮件

19、访问数据库

使用SQLite------嵌入式数据库

使用MySQL

使用SQLAIchemy

20、Web开发

HTTP协议简介

HTML简介

小结

WSGI 接口

使用Web框架

使用模板

21、异步IO

协程

asyncio

小结

async/await

aiohttp

22、实战


壹、简单入门(安装Python就不说啦,仅Windows系统)

1、Python的交互模式:Python大小写敏感

注意区分命令模式和Python的交互模式

①在cmd的命令模式下输入Python回车,Python的提示符是,之后就可以输入Python代码执行

②完了之后输入 exit() ,退出Python的交互模式即可回到命令模式,注意要注意中英文符号,Python区分大小写的

③也可以在命令模式下执行一个 文件,注意:执行一个文件只能在命令模式下执行,如果在交互模式下会报错的

④在Python的交互模式下,可以直接输入代码,然后执行得到结果,而在命令模式,则直接运行文件

2、练习1:

在Python的交互模式下,输入代码(先试着看看数值的加减)后直接回车:

3、基础的函数

(1)让Python打印出指定的文字,用print()函数

(注意:文字用单引号或者双引号都可以,记得是英文符号就可以了!)单引号或者双引号括起来的文本叫字符串

贰、尝试第一个Python程序

1、练习:

(用文本编辑器,可以用sublime或者notepad++,像我用的即使notepad++,不要用记事本!)

保存的时候记得保存为 “ .py ” 的文件,此外,文件名只能是英文字母、数字、下划线组成。

记得运行 .py 文件之前,记得用cd 切换成当前的目录,如果是其他目录,可以搜一下怎么切换成那个目录

在Python的交互模式下运行代码和直接运行 .py 文件的区别:

在Python的交互模式,相当于启动了Python的解释器,等待你一行一行输入源代码,每输入一行就执行一行;

直接运行 .py 文件相当于你启动Python的解释器,然后一次性把所有的源代码给执行了,你是没有机会一交互的方式输入源代码的

2、Python代码运行助手

这个就是你在网上学习Python时,直接在他们的网页上输入代码运行的,所有就要用到Python代码运行助手,以便你看到结果,这个就不说了。

3、输入和输出

(1)输出:print()

①在print() 的括号中输入字符串,就可以向屏幕输出指定的文字,比如输出 “hello world 你好世界 ”

(呃,才发现我打多了个字母了。。)

②print() 函数也可以接受多个字符串,用 “ , ” 隔开,就可以了(注意:逗号相当于一个空格隔开,然后继续连接字符串)

③print() 可以打印整数,或者计算结果,或者直接弄成一个等式也是可以的(注意:第三行的print中 ‘100+300’ 是字符串)

(2)输入input() ,让用户向电脑输入字符

Python提供了一个input() ,可以让用户输入字符串,并存放到一个变量里。

(input() 返回的数据类型是 str ,str 不能直接和整数比较,必须把 str 转换成整数,如:

 

如,让用户输入自己的名字

当输入 name = input() 后,直接按回车,这时候Python交互式命令行就等待你输入了,这时你可以输入任何字符,然后回车完成就可以了,这样状态又变成了Python交互模式的 >>> 了,不会有任何提示,但是你刚刚输入的内容是存放的name这个变量里的

①你可以输入变量name查看内容

②或者你也可以输入函数print() 查看变量(注意,这时候你是要查看变量name的内容的,而不是打印字符串,所以不用加引号)

③结合输入输出练习

a、把输出 hello world 改成向用户say hello(白色的是在notepad中编辑,黑色的是直接运行 .py 文件的)

让用户输入自己的名字后,向用户问好

b、但是没有任何提示说明来解释,有点不够友好,加点说明,input() 还可以加点字符串来提示用户,可以将代码改成

每次运行该程序,根据用户输入的不同,输出也会不同的,在命令行下,输入输出比较简单。

小结:

输出是output(),输入和输出 input()/output() 称为IO (其实output和print有什么不同我好像还没有弄区分。。)

input() 和print() 是命令行下最简单的输入和输出了

叁 Python基础

1、数据类型 和 变量

①整数(也包括负整数)---int()

②浮点数(也就是小数)---float()

③字符串------str()

字符串是由单引号或者双引号括起来的任意文本,单引号 ‘ ’ 或者双引号 " " 本身只是一种表示方式,不是字符串的一部分

如果引号也是字符串中的字符,那么应该用另外一种引号来括起来

如果字符串中既包含单引号 '' ,又包含双引号 "" ,就可以用转义字符 \ 来标识

转义字符 \ 可以转义很多字符,如 \n 表示换行,\t 表示制表符,字符 \ 本身也要转义,所以 \\ 表示的字符就是 \

若字符串内需要有很多行,那么\n 换行很不方便,因此Python可以用  ''' ...many ''' 三个单引号一起表示多行内容,当>>>变成三个点 ... 时,可以继续输入,而提示符三个点不是代码的一部分

在notepad++上编辑,试试 .py 文件运行(注意:在文本编辑器中,没有提示符... 的,直接输入就可以了) 

多行字符串还可以在前面加上 r 使用

④布尔值----True 和 False

一个布尔值只有 True 和 False 两种值,可以直接用 Ture 或 False 表示布尔值(注意大小写),也可以通过布尔运算出来

布尔值可以通过 andornot 运算(感觉有点像数学的真假命题一样)

a、and 运算是与运算,只有所有结果为 true ,结果才为 true

b、or 运算是或运算,只要其中有一个为 true,结果为 true

c、not 运算是非运算,它是一个单目运算符(运算中只有一个操作数),把 true 变成 false,把 false 变成 true

d、实际运用:布尔值经常用在条件判断中

⑤空值-----None

空值是Python中的一个特殊的指,用 None 表示,none 不能理解为 0 ,0 是有意义的,而 None 是一个特殊的空值

⑥变量

变量名必须是 大小写英文,数字 或者 下划线 _ ,且不能用数字开头

如,变量a是一个整数,变量 t_007 是一个字符串,变量Answer是一个布尔值

(在Python中,等号 = 是赋值语句,可以把 任意数据类型 赋值给 变量,同一个变量可以反复赋值,而且可以是不同类型的变量)

⑦常量---除法(/ 或者 //)---求余(%)

a、常量就是不能变的变量,在Python中,通常用  全部大写的变量名 表示常量(习惯上的用法)

b、Python中有两种除法, /  和  //  (具体解释自行百度)

要做精确的除法,使用 /  就可以了, //  除法永远是整数

c、余数运算 %,可以得到两个整数相除的余数

2、字符串和编码

①字符编码

美国的编码:ASCII(仅英文字母)

中国加了中文:GB2312

各国有各国的标准,都有加了自己国家语言的编码

所有语言统一到一套编码里:Unicode

可变长编码:UTF-8(其实就是Unicode的简版吧,在浏览器里,Unicode和UTF-8可以随意方便快捷转换)

②字符串 str 

a、对于单个字符的编码,Python提供了 ord() 函数 获取字符的 整数表示,chr() 函数 把编码 转换为对应的字符

b、Python的字符串类型是 str ,以Unicode表示的 str 通过 encode() 方法 可以编码成指定的 bytes,要把 bytes 变成 str ,就需要用到decode() 方法,(详细的 str 和 bytes 可以自行百度)

c、要计算 str 包含多少字符,可以用 len() 函数 

len() 函数 计算的是str的字符数,如果换成是bytes,len() 函数 就计算字节数)

为了避免乱码问题,应该使用UTF-8 编码对 str 和 bytes 进行转换

 

③格式化 %

如何输出格式化字符串?

在Python中,采用格式化方式和 C语言一样,用 % 实现

% 运算符就是用来格式化字符串的。

在字符串内部, %s 表示字符串替换, %d 表示用整数替换,有几个 %? 占位符,后面就跟几个变量或者值,顺序要对应好,如果只有一个 %? ,括号可以省略

(其中,格式化整数和浮点数还可以指定是否补0 和  整数与小数的位数)

如果不确定应该用什么,%s 永远起作用,它会把任何数据类型转换为字符串

有时候,字符串里的 % 只是一个普通的字符,这时候就需要转义了,用 %% 来表示一个 %

另一种格式化字符串的方法是使用字符串的 format() 方法,不过比较麻烦。

格式化字符串的时候,可以用Python的交互式环境测试,方便快捷

3、使用 list[] 和 tuple ()

① list:有序集合 [ ]-----len()获得集合或元组中元素的个数

a、list是一种有序集合,可以随时 添加 和 删除 其中的元素,如:

列出班上所有人的名字,变量classmates就是一个list

然后classmates进行查看,接着用 len() 函数获得 list 元素的个数

b、可以用 索引 来访问 list 中某一个位置的元素,记得索引是从 0 开始的,当索引超出了范围是,Python会报错,

最后一个元素的索引是 -1,以此类推,可以获得倒数第二第三的元素

c、list 是一个可变的有序列表,可追加、插入、删除、替换

所以可以往 list 中追加元素 到末尾(.append()

可以把元素插入到 list 指定位置(.insert()

删除 list 元素(.pop()),删除末尾元素 .pop(),删除指定位置的元素  .pop(i) ,i 是索引位置

要把某个元素替换成别的元素,可以直接赋值给对应的索引位置

d、list 中的数据类型也可以不同

e、list 中还可以有 list ,其中,N有三个元素,N[2] 又是里面的 list 了

或者拆开写也行的,要拿到 yan ,可以写 v[2][0] 或者 q[0] 

如果 list 中一个元素也没有,就是一个空的 list,它的长度为零

②tuple():有序列表的元组(和 list 很相似)

a、但 tuple 一旦初始化就不能修改,因此 tuple是没有像 追加、插入、删除、替换这些的,但是其他获取元素的方法和 list 一样

因为 tuple 设定的变量是不可变的,所以代码更安全(这个我也不是很能理解),因此能用 tuple 的尽量选择 tuple,但是如果 tuple 中有 list,tuple指向的 list是不可变的,但是 list 中的变量是可变的

b、定义一个空的 tuple 时,可以写成 ( )

但如果定义只有一个元素的 tuple ,必须加一个逗号来消除歧义(因为括号 ( ) 既可以表示 tuple,也可以表示数学公式中的小括号,这就产生了歧义,因此Python定义,在这种情况下按小括号计算,Python在显示的时候也会加上一个小括号,以免你误会成数学计算意义上的括号

 

小结:list和tuple都是Python中的有序集合,但list可变,tuple不可变

4、条件判断---- if

计算机之所以能做很多自动化的任务,是因为它能自己做条件判断

a、比如简单的根据 用户的年龄 判断 用户的年龄阶层,用 if 语句实现:(注意不要少写了冒号

(elif 是 else if 的缩写,完全可以有多个 elif ),所以 if 的完整句式是:(if 语句有个特点,它是从上往下判断的,如果在某个判断上是True,那么把改判断的对应语句执行后,就忽略剩下的elif 和 else)

5、循环(Python的循环有两种)------① for ... in ------② while x

forin list / tuple : -------range()

依次把 list 或 tuple 中的元素迭代出来

for x in y :就是 y 中的每个元素代入到 x 中,然后执行缩进块的语句

a、再比如计算整数1-10之间的和,可以用一个sum变量做累加

放一个错误的图片,记得代码块的缩进不同,呈现的结果也是不一样的下图的 print 也跟着一起缩进了,所以循环打印每一次的sum的结果

这一次正确,每一次循环计算sum的结果,print 输出的是最后得出的sum

b、如果计算的是1-100的结果,甚至是很多很多连续数字的总和,就不能把数字一个个打上了,这时候就需要一个可以生成一个序列的方法,Python提供了 range() 函数,可以生成一个整数的数列,再通过 list() 函数可以转换为 list ,如range(5) 生成的是一个从0开始小于5的数列

现在开始计算0-100的和(这是我自己敲的代码,我看看了老师的代码,其实第三行中,是直接 for L in range(101)的 

注意 range() 的使用,得用 list()才会直接显示里面所有的元素

while x :

只要条件满足,就不断循环,条件不满足时退出循环

a、比如我们要计算0-100之间奇数的和,就可以用while循环(注意:这是我自己写的代码)

看看老师的代码

break--------通常配合 if 使用

在循环中,break语句 可以提前退出循环

比如本来要打印出0-100的数(我没注意设成无限打印整数了),但是在n>10,提前终止打印

(笑哭,我每次自己打的代码都和老师打的不大一样,虽然结果相同,都是按照我自己的思路来打的)

continue----通常配合 if 使用

在循环过程中,通过continue跳过当前循环,直接开始下一次循环

如本来应该打印0-10的数字的,但加了continue直接打印0-10的奇数,跳过偶数的循环 (或者说 提前结束偶数的循环)

小结:

循环是让计算机 做重复任务 的有效方法。

注意:不要滥用 break 和 continue 语句,break 和 continue 会造成 代码执行逻辑 分叉过多,容易出错,大多数循环并不需要用到 break 和 continue 语句。这两个语句通常都必须配合 if 语句使用

有时候,如果代码写得有问题,会让程序陷入死循环,也就是永远循环下去,这时可以用 ctrl+c 退出程序,或者强制退出Python进程

6、使用dict{} 和 set ()----不是很明白怎么用,先过一遍,再回来深入学习

dict{}

set()

set 和 dict 类似,也是一组key集合,但不储存value。由于key不能重复,所以在set中,没有重复的key 

add(key)  、remove(key)

 

肆、函数-------卡住了,不是很明白怎么用,先过一遍,再回来深入学习

1、调用函数

(1)调用函数

①求绝对值的函数 abs()

②函数 max()、min()、sum()

(2)数据类型转换 int()

int() 整数

float() 浮点数

str() 字符串

bool() 布尔值

hex() 把整数转换成十六进制表示的字符串

2、定义函数

(1)定义函数--- def() 语句---

定义一个函数,要使用 def() 语句,(def  函数名(函数):) 

(2)空函数--- pass语句

(3)参数检查

(4)返回多个值

3、函数的参数

power()、enroll()、calc()、person()、

(1)位置参数

(2)默认参数

(3)可变参数

(4)关键字参数

(5)命名关键字参数(*

(6)参数组合

4、递归函数 fact() ---------

 

伍、高效特性

在Python中,代码不是越多越好,而是越少越好,代码不是越复杂越好,而是越简单越好。

代码越少,开发效率越高。

1、切片(Slice)

在 list 或 tuple 取出部分元素,比如一个 list 如下:

 

比较笨的麻烦的方法是,如果要取前 n 个就麻烦了

取前n个元素,也就是索引为 0--(n-1)的元素,可以用循环,但也有点麻烦

因此Python提供了切片方法解决这个问题,用一行代码完成切片

s[0:3] 表示,索引从 0 开始,到3为止,但不包括索引 3

如果第一个索引是0 ,还可以省略(奇怪,看廖老师的可以但我的不可以)

(我再看看我的代码,发现是我自己打错了:

当然,倒数的索引也支持,记住倒数第一个索引是 -1

切片操作十分有用啦,比如先创建一个0-99的数列,

然后取出其中前22个元素、取出第11个数到第20的元素、取出最后4个数和倒数第五个数

前十个数,每隔2个取一个数

前从索引为2开始,前十个数,每隔三个取一个

每隔5个取一个

原样复制一个 list 

tuple 也是一个 list,区别的是 tuple 不可变

字符串 'xxx' 也可以看成一个 list,每个元素就是一个字符,因此字符串也可以进行切片 ,只是操作结果仍然是字符串

 

2、迭代----(for...in)

定义:给定一个 list 或者 tuple ,用 for 循环来遍历这个 list 或者 tuple,这种遍历就叫迭代。

在Python中,迭代就是通过 for...in 来完成的

 

3、列表生成式

列表生成即 list Comprehensions,用来创建 list 的生成式

举个例子,要生成 list[1,2,3,...,10] 可以用 list(range(1,11)) -----list(range(n,m))

但如果要生成[1x1,2x2,3x3,...,10x10]怎么做?方法一是循环:

但是循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的 list :[x * x for x in range(n,m)]

for 循环后面还可以加 if 判断,这样就可以筛选想要的---[x * x for x in range(n,m) if x % y == 0 ]

如只要1到10的偶数平方

还可以使用两层循环,生成全排列

三层或三层以上的循环就很少用了

运用列表生成式,可以写出非常简洁的代码,还可以列出当前目录下所有文件和目录名,可以通过一行代码实现

for 循环可以同时使用两个甚至是多个变量,比如 dictitems() 可以同时迭代 key 和 value

列表生成式也用两个变量生成 list,(注意,我 item 漏了复数 s 直接报错)

最后一个,把字符串中的所有字符变成小写:------lower()(非字符串类型没有 lower() 方法)

使用内建 isinstance() 函数可以判断一个变量是不是字符串(或者判断是不是整数浮点数等等都可以)

运用列表生成式,可以快速生成 list,可以通过一个 list 推导出另一个 list ,而代码十分简洁。

4、生成器 generator------generator也是可迭代对象

一边循环一遍计算的机制,就叫做生成器。创建一个 generator有很多种方法

第一种方法,把一个列表生成式的 [ ] 改成 ( ),就创建了一个 generator

创建 L 和 g 的区别在于 最外层的 [ ] ( ) L 是一个 list,而 g 则是一个 generator。

我们可以打印出 list 的每一个元素,那应该怎么打印 generator 的元素呢,若是一个个打印出来,则可以通过函数 next() 获得下一个返回值。

用函数 next() 获得 generator 的下一个返回值:

我们创建了一个generator,基本上永远不会调用 next() 函数,而是用 for 循环来迭代它。

如果推算的算法比较复杂,用类似列表生成式的 for 循环无法实现的时候,还可以用函数来实现。

比如 斐波拉契数列(Fibonacci),除第一个和第二个数以外,任意一个数都可以由前两个数相加得到:

1, 1, 2, 3, 5, 8, 13, 21, 34, ...

斐波拉契数列用列表生成式写不出来,但用函数把它打印出来却很容易:(可以输出斐波拉契数列的前 n 个数)

fib 函数 实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。也就是说,上面的函数和generator仅一步之遥,要把 fib 函数变成generator,只需要把 print(b) 变成 yield b 就可以了

这是定义 generator 的第二种方法。如果定义一个函数中包含 yield 关键字,那么这个函数就不再是一个普通的函数,而是一个generator:

(当然啦,我发现直接 fib(max)  也可以)

generator 和函数的执行流程不一样,函数是顺序执行,遇到 return语句 或者 最后一行函数 就会返回,而变成了generator的函数,在每次调用 next() 的时候执行,遇到 yield 语句就返回,再执行时就从上次停顿的 yield 语句处继续执行。

…………后面的没看懂。。。

 

5、迭代器

可直接作用于 for  循环的数据类型:

a、集合数据类型:list[ ] 、tuple() 、str()、dict()、set() 等

b、generator,包括 生成器 和 带 yield 的generator function

这些可直接作用于 for 循环的对象,可统称为 可迭代对象 Iterable

可以使用 isinstance() 判断一个对象是否是 Iterable 对象

生成器都是 iterable 对象,但 list 、dict 、str 虽然是 Itable,却不是 Iterator 

这是因为Python的 Iterator 对象表示的是一个数据流,Iterator 对象可以被 next() 函数调用并不断返回下一个数据,直到没有数据时抛出一个 StopIteration 错误,可以把这个数据流当成一个有序序列,我们却不能提前知道这个序列的长度,只能不断通过 next() 函数实现 按需计算下一个数据,所以 Iterator计算是惰性的,只有在需要返回下一个数据是它才会计算。 

Iterator 甚至可以表示一个无限大的数据流,例如全体自然数,而使用list 是永远不可能存储全体自然数的。

凡是可作用于 for 循环的对象都是 Iterable 类型

凡是可作用于 next() 函数的对象都 Iterator类型,他们表示一个惰性计算的序列

复合数据类型如 list 、dict 、str 等是 Iterable 而不是 Iterator,不过可以通过 Iter() 函数获得一个 Iterator 对象

Python 的 for 循环本质上就是通过不断调用 next() 函数实现的,例如:

陆、函数式编程

1、高阶函数(higher-order function):一个函数可以接受另一个函数作为参数

变量可以指向函数

函数名也是变量

传入函数

① map / reduce

map() 函数接受两个参数,一个是函数,一个是 Iterable

reduce() 把一个函数作用在一个序列

map() 作为高阶函数,不但可以计算简单 f(x) = x²,比如吧 list 中的所有数字转为字符串,只需一行代码 :list(map(str,[ ]))

② filter() ---- 用于过滤序列---- 关键在于正确实现一个 “ 筛选” 函数----- filter的作用是从一个序列中筛选出符合条件的元素

filter 与map 相似,也接受一个函数一个序列,但不同的是,filter 把传入的函数依次作用于每个元素。然后根据返回值是true还是false决定保留还是丢弃该元素

要注意,filter() 返回的是一个 Iterator,也是一个惰性序列,所以要强迫 filter() 返回计算结果,需要用 list 函数获得所有结果并返回 list

③ sorted 

排序算法

排序的核心是比较两个元素的大小,如果是数字可以直接比较,那如果是字符串或者dict呢,应该怎么比较?

sorted也是一个高阶函数,还可以接受一个key函数来自定义排序,

对字符串进行排序,默认情况下,是按照ASCII 的大小比较的,由于 'Z' <  'a',大写字母 Z 会排在 小写字母 a 前面

忽略大小写,按字母序排序(实际就是先把字符串全部变成大写或者小写),在传入第三个参数 reverse=True后,进行反向排序

sorted 关键在于实现一个映射函数

练习:operator.itemgetter(),函数 itemgetter 用于获取对象的哪些维的数据,参数为一些序号

如下面的,按成绩来将学生排序:

2、返回函数

 

3、匿名函数----lambda()

匿名函数 lambda,只能有一个表达式,不用写 return,返回值就是该表达式的结果

4、装饰器-----decorator(),在代码运行期间动态增加功能的方式

decorator是一个返回函数的高阶函数

记得在定义 wrapper 的前面加上

5、偏函数----partial()

 

柒、模块

模块:在Python中,一个 .py 文件就称之为一个模块(Module)

包:按目录组织模块的方法,称之为包(package)。每个包下面都会有一个 _init_.py 的文件,这个文件是必须存在的,否则,Python就把这个目录当成是普通的目录,而不是一个包

创建自己的模块时,要注意:

模块名要遵循Python变量命名规范,不要使用中文、特殊字符;

模块名不要和系统模块名冲突,最好先检查系统是否已存在该模块,检查方法是在Python交互环境下执行 import abc(abc是模块名),若成功则说明系统存在此模块。

1、使用模块

特殊变量:__xx__(注意,左右两边是两个下划线),可以直接被引用

作用域

类似 _xx__xx 这样的函数或变量就是非公开的(private),不应该被直接引用

2、安装第三方模块

 

 

捌、面向对象编程

1、类(class)和实例(Instance)

类名通常大写开头的字母

创建实例是通过类名+() 实现的:

可以看到,变量bart指向的就是一个Student的实例,后面的0x10a67a590是内存地址,每个object的地址都不一样,而Student本身则是一个类。

 

__init__-----特殊方法“__init__”前后分别有两个下划线!!!

注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self因为self就指向创建的实例本身

有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去:

和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。

数据封装

2、访问限制

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问

需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name____score__这样的变量名。

有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。

3、继承和多态

在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。

run() 方法可以直接打印

当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。这样,我们就获得了继承的另一个好处:多态。

判断一个变量是否是某个类型可以用isinstance()判断:

4、获取对象信息

使用 type() 函数------判断对象类型

基本类型都可以用 type 判断

例如:

比较两个变量的 type类型是否相同

使用 isinstance() 函数-----判断class类型

对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。

能用type()判断的基本类型也可以用isinstance()判断:

并且还可以判断一个变量是否是某些类型中的一种,比如下面的代码就可以判断是否是list或者tuple(只有是其中一个类型就ok)

使用 dir() 

如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:

仅仅把属性和方法列出来的是不够的,配合hasatter()、setatter()、getatter(),直接操作一个对象的状态,测试该对象的属性:

可以传入一个 default 值,如果属性不在就返回默认值

 

5、实例属性和类属性

由于Python是动态语言,根据类创建的实例可以任意绑定属性。

给实例绑定属性的方法是通过实例变量,或者通过self变量:

 

 

在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。

 

 

玖、面向高级对象编程

多重继承、定制类,元类

1、使用__slots__

创建一个实例,给该实例定义属性和方法,调用实例方法

给一个实例绑定的方法,对另一个实例是不起作用的

为了给所有实例都绑定方法,可以给class绑定方法,给class绑定方法后,所有实例均可调用

使用__slots__限制该class实例 能添加 的属性(用tuple定义允许绑定的属性名称)

__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__

下面是自己照着打的代码:(有需要的可以直接看去廖老师的官网学习)

2、使用 @property

如果把属性直接暴露出去,就没办法检查参数,导致可以把成绩随意改

这显然不合逻辑。为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数:

但是,上面的调用方法又略显复杂,没有直接用属性这么直接简单。

有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?对于追求完美的Python程序员来说,这是必须要做到的!

还记得装饰器(decorator)可以给函数动态加上功能吗?对于类的方法,装饰器一样起作用。Python内置的@property装饰器就是负责把一个方法变成属性调用的

@property的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:

注意到这个神奇的@property,我们在对实例属性操作的时候,就知道该属性很可能不是直接暴露的,而是通过getter和setter方法来实现的

还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:

3、多重继承

MixIn

MixIn的目的就是为了给类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个MixIn功能,而不是设计多层次的复杂的继承关系

小结

由于Python允许使用多重继承,因此,MixIn就是一种常见的设计

只允许单一继承的(如Java)不能使用MixIn设计

4、定制类

__str__

这样打印出来的实例,不但好看,而且容易看出实例内部重要的数据。

直接敲变量不用print,打印出来的实例还是不好看:

__repr__ 返回一个好看的字符串

这是因为直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。

解决办法是再定义一个__repr__()。但是通常__str__()__repr__()代码都是一样的,所以,有个偷懒的写法:

__iter__ ----返回一个迭代对象

 

__getitem__

 

__getattr__

 

__call__ --定义一个__call__()方法,就可以直接对实例进行调用

一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()来调用。能不能直接在实例本身上调用呢?在Python中,答案是肯定的。

任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用。请看示例:

调用如下:

通过 callable() 函数 ,我们可以判断一个对象是不是 “ 可调用 ”对象

Python还有很多可定制的方法,这里只是其中常用几种。

5、使用枚举类-----Enum类

这样我们就获得了Month类型的枚举类,可以直接用Month.Jan来引用一个常量,或者枚举它的所有成员

value属性是自动赋给成员的 int常量,默认从 1 开始数

如果需要更精确的控制枚举类型,可以从Enum派生出自定义类:

@unique 装饰器可以帮助我们检查保证没有重复值

访问这些枚举类型有若干种方法:

可见,既可以用成员名称引用枚举常量,又可以直接根据value的值获得枚举常量

6、使用元类

type()-------动态创建类

动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。

type() 函数可以查看一个类型或者变量的类型

type() 函数既可以返回一个对象的类型,又可以创建一个新的类型

要创建一个class对象,type() 函数依次传入3个参数:

①、class的名称;

②、继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元数写法;

③class 的 方法名称和函数 绑定。

metaclass()---------元类

先定义metaclass,就可以创建类,最后创建实例

所以,metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”

 

拾、错误、调试和测试

错误(bug):程序编写、用户输入、异常

调试:跟踪程序的执行,查看变量的值是否正确

测试:编写测试也很重要。有了良好的测试,就可以在程序修改后反复运行,确保程序输出符合我们编写的的测试。

错误处理

常见的错误类型和继承关系看廖老师的文档:https://docs.python.org/3/library/exceptions.html#exception-hierarchy

try...except...finally

try

调用栈

记录错误

抛出错误

 

调试

断言(assert)

logging-----终极武器

pdb

 

单元测试

 

setUp 、 tearDown

 

文档测试

 

拾、IO编程(本章都是同步IO)

是否等待IO执行的结果——同步IO、异步IO(回调模式、轮间模式)

文件读写

 

在Python中,文件读写是通过open()函数打开的文件对象完成的,使用with语句操作文件IO是个好习惯。

 

StringIO 和 BytesIO

StringIO 和 BytesIO 是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口

 

操作文件和目录

环境变量

在操作系统中定义的环境变量,全部保存在os.environ这个变量中,可以直接查看:

操作文件和目录

操作文件和目录的函数一部分放在os模块中,一部分放在os.path模块中,这一点要注意一下。

把两个路径合成一个时,不要直接拼字符串,而要通过os.path.join()函数;

同样的道理,要拆分路径时,也不要直接去拆字符串,而要通过os.path.split()函数。

shutil模块提供了copyfile()的函数,你还可以在shutil模块中找到很多实用函数,它们可以看做是os模块的补充。

列出所有的 .py 文件,也只需要一行代码

小结

Python的os模块封装了操作系统的目录和文件操作,要注意这些函数有的在os模块中,有的在os.path模块中

序列化(pickling)

把变量从内存中变成可存储或者传输的过程称之为序列化

Python提供 pickle 模块来实现序列化。

Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。

 

JSON

json.dumps是将一个Python数据类型列表进行json格式的编码解析,

json.dump和json.dumps很不同,json.dump主要用来json文件读写,和json.load函数配合使用。

json.dump(x,f),x是对象,f是一个文件对象,这个方法可以将json字符串写入到文本文件中。

Python语言特定的序列化模块是pickle,但如果要把序列化搞得更通用、更符合Web标准,就可以使用json模块。

11、进程和线程

多进程

要实现跨平台的多进程,可以使用multiprocessing模块

多线程

ThreadLocal

一个ThreadLocal变量虽然是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal解决了参数在一个线程中各个函数之间互相传递的问题。

进程 vs 线程

12、正则表达式

re模块,包含所有正则表达式的功能

切分字符串

分组

贪婪匹配

编译

13、常用内建模块

detatime

获取当前日期和时间

获取指定日期和时间

datetime转换为timestamp

str转换为datetime

detatime转换为str(strftime())

detatime加减(detadelta)

本地时间转换为UTC时间(tzinfo)

时区转换(utcnow())

小结

datetime表示的时间需要时区信息才能确定一个特定的时间,否则只能视为本地时间。

如果要存储datetime,最佳方法是将其转换为timestamp再存储,因为timestamp的值与时区完全无关。

collections

namedtuple

deque

defaultdict

OrderedDict

ChainMap

Counter

base64

struct

hashlib(摘要算法)

hmac

itertools====提供了用于操作迭代对象的函数

contextlib

@contextmanager

@closing

urllib=======利用程序去执行各种HTTP请求

post

get

Handle

XML

DOM vs SAX(start_element、end_element、char_data)

会产生3个事件:

  1. start_element事件,在读取<a href="/">时;

  2. char_data事件,在读取python时;

  3. end_element事件,在读取</a>

HTMLParse

feed()

利用HTMLParser,可以把网页中的文本、图像等解析出来。

14、常用第三方模块

Pillow

requests-------获取URL资源

chardet------检测编码

psutil-------实现系统监控

获取网络接口和网络连接信息

15、virtualenv-----隔离的python运行环境

16、图形界面

Tkinter

第一个GUI程序

 

海龟绘图

turtle 包本身只是一个绘图包

调用width()函数可以设置笔刷宽度,调用pencolor()函数可以设置颜色。更多操作请参考turtle库的说明。

绘图完成后,记得调用done()函数,让窗口进入消息循环,等待被关闭。否则,由于Python进程会立刻结束,将导致窗口被立刻关闭。

①第一个照着源代码的:

②自己练习的

 

17、网络编程

TCP/IP简介

TCP编程

UDP编程

18、电子邮件

SMTP发送邮件-------发送邮件的协议

POP3收取邮件

poplib模块

19、访问数据库

noSQL

数据库类别

使用SQLite------嵌入式数据库

Python就内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。

要操作关系数据库,首先需要连接到数据库,一个数据库连接称为Connection;

连接到数据库后,需要打开游标,称之为Cursor,通过Cursor执行SQL语句,然后,获得执行结果。

使用MySQL

执行INSERT等操作后要调用commit()提交事务

MySQL的SQL占位符是%s

使用SQLAIchemy

ORM框架的作用就是把数据库表的一行记录与一个对象互相做自动转换。

正确使用ORM的前提是了解关系数据库的原理。

20、Web开发

HTTP协议简介

HTML简介

小结

如果要学习Web开发,首先要对HTML、CSS和JavaScript作一定的了解。HTML定义了页面的内容,CSS来控制页面元素的样式,而JavaScript负责页面的交互逻辑。

讲解HTML、CSS和JavaScript就可以写3本书,对于优秀的Web开发人员来说,精通HTML、CSS和JavaScript是必须的,这里推荐一个在线学习网站w3schools:

http://www.w3schools.com/

以及一个对应的中文版本:

http://www.w3school.com.cn/

当我们用Python或者其他语言开发Web应用时,我们就是要在服务器端动态创建出HTML,这样,浏览器就会向不同的用户显示出不同的Web页面。

WSGI 接口

使用Web框架

使用模板

21、异步IO

使用异步IO将大大提升系统的多任务处理能力

协程

asyncio

小结

asyncio提供了完善的异步IO支持;

异步操作需要在coroutine中通过yield from完成;

多个coroutine可以封装成一组Task然后并发执行。

async/await

asyncio提供的@asyncio.coroutine可以把一个generator标记为coroutine类型,然后在coroutine内部用yield from调用另一个coroutine实现异步操作。

为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法asyncawait,可以让coroutine的代码更简洁易读。

请注意,asyncawait是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换:

①把@asyncio.coroutine替换为async

②把yield from替换为await

aiohttp

22、实战

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值