1. python3.x特性
1.1. python编码问题
- python3.x 默认的内部编码是Unicode,默认的文件编码是utf-8
- 代码中的字符串的默认编码与代码文件本身的编码是一致的
- python的内部编码为unicode,与文件本身的编码无关
1.1.1. 声明文件编码
# -*- coding: UTF-8 -*-
#coding=utf-8
1.1.2. 文件编码
文件本身的编码指的是文件保存在磁盘上时所使用的字符编码,通常使用UTF-8编码或其他编码方式
1.1.3. 内部编码
内部编码指的是Python解释器在内存中使用的字符编码,也是默认的字符串编码方式。Python 3.x 中默认的内部编码是Unicode(UTF-8编码的一种),所以支持多种语言和字符集。当我们读取文件或从其他数据源中获取数据时,Python会自动将其转换为内部编码,当我们将数据写入文件或在屏幕上输出时,Python也会自动将其转换为指定的编码方式。
这一点和 Java 一样
1.2. 其他特性
- python对大小写敏感
- python通过缩进来控制结构层次(通常4个空格为一个标准缩进)
- 使用斜杠
\
实现换行代码的衔接 - id() 获取内存地址
- type() 获取数据类型
- help(方法名称) 查看某方法的使用
- import + 库名 导入库
- 库名.方法名 调用库中某方法
- python库安装和卸载
安装:pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple
卸载: pip uninstall 库名
- 更新pip
cmd下运行python -m pip install --upgrade pip
2. python编写规范
3. python编译
.pyc
文件是py文件编译后生成的字节码文件(byte code)。pyc文件经过python解释器最终会生成机器码运行。所以pyc文件是可以跨平台部署的,类似Java的.class文件。
生成单个pyc文件
python -m foo.py
批量生成pyc文件
python -m compileall <dir>
4. 交互式编程
即直接在终端(如 cmd )中运行解释器,而不使用文件名的方式来执行文件。这种交互式的编程环境,我们也可以称之为REPL,即读取(Read)输入的内容,执行(Eval)用户输入的指令,打印(Print)执行结果,然后进行循环(Loop),Python支持交互式编程
ipython
是一个python
的交互式shell
,比默认的python shell
好用得多,支持变量自动补全,自动缩进,支持bash shell
命令,内置了许多很有用的功能和函数
5. 注释符
#
6. 变量
只要定义了一个变量,而且它有数据,那么它的类型就已经确定了,不需要开发者主动的去说明它的类型,系统会自动辨别。变量没有类型,数据才有类型
同时为多个变量赋值
x, y, z = "Orange", "Banana", "Cherry"
交换a b的值
a,b=b,a
+
号连接字符
x = "awesome"
print("Python is " + x)
*
重复多次
x= 'abc'
print(x*2)
#结果为 abcabc
7. 数据类型
7.1. 数字类型(Number)
包括整型、浮点型、复数等
7.2. 字符串类型(String)
用于表示文本数据,可以使用单引号、双引号或三引号来定义字符串
7.3. 列表类型(List)
用于存储一组有序的元素,可以包含不同类型的元素,通过索引访问元素。
7.4. 元组类型(Tuple)
类似于列表,但是元组中的元素不可修改,通常用于存储不可变的数据。
7.5. 集合类型(Set)
用于存储一组不重复的元素,可以进行交、并、差等集合运算。
7.6. 字典类型(Dictionary)
用于存储键值对,可以通过键来访问对应的值,键必须是不可变的类型。
7.7. 布尔类型(Boolean)
用于表示真(True)和假(False)两种状态。
不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组)
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)
7.8. 常用运算
科学计数
科学计数法:
1.5 x 10^11表示为:
1.5e11
这里e和E不区分大小写
复数
复数由实数部分和虚数部分组成,实数部分和虚数部分都是浮点型,虚数部分必须有后缀j或J
print (64.375+1j)
结果为64.375+1j
7.9. 类型转换
- set(s) 转换为可变集合
- int() 转换为整型
- str() 转换为字符型
- float() 转换为浮点型
- bool(x) 布尔型转换
在python3中,只有空字符串''
、""
、数字0、空字典{}
、空列表[]
、空元组()
、空数据None会被转换成为False,其他的都会被转换成为True
- unichr(x) ASCII码转为Unicode单字符串
- abs() 取绝对值
- round 四舍五入保留指定小数位
- sum 求和
- type() 查看数据的类型
8. 标识符
标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名
8.1. 标识符命名
-
由字母、下划线和数字组成,且数字不能开头
-
严格区分大小写
-
不能使用关键字
8.2. 驼峰命名法
-
大驼峰命名法:FirstName、LastName
-
小驼峰命名法:myName、aDog
注意
- 变量名,函数名和文件名全小写,使用下划线连接
- 类名遵守大驼峰命名法
- 常量名全大写
9. 关键字
一些具有特殊功能的标识符
10. 输入输出
10.1. 输入(input)
10.1.1. 语法
返回字符串类型
input('提示信息')
同时输入多个值
a,b,c=input().split(' ') #输入a,b,c时 将a、b、c用空格隔开
10.2. 输出(print)
10.2.1. 语法
print(value,sep,end)
10.2.2. 参数
sep
输出时,每个值使用哪种符号分割,默认使用空格
print(123,789,sep='----')
#结果是 123----789
end
执行完一个print语句后,接下来要输出的字符,默认是\n
print(123,789,end='????')
#结果是 123 789????
10.2.3. 格式化输出
格式符号 | 转换 |
---|---|
%% |
输出 % 号 |
%s |
字符串 |
%d |
有符号十进制整数 |
%f |
浮点数 |
%c |
字符 |
%u |
无符号十进制整数 |
%o |
八进制整数 |
%x |
十六进制整数(小写字母0x ) |
%X |
十六进制整数(大写字母0X ) |
%e |
科学计数法(小写e ) |
%E |
科学计数法(大写E ) |
%g |
%f 和%e 的简写 |
%G |
%f 和%E 的简写 |
格式化操作符辅助指令
符号 | 功能 |
---|---|
* | 定义宽度或者小数点精度 |
- | 用做左对齐 |
+ | 在正数前面显示加号( + ) |
<sp> |
在正数前面显示空格 |
# |
在八进制数前面显示零0 ,在十六进制前面显示0x 或者0X |
0 | 显示的数字前面填充’0’而不是默认的空格 |
(var) | 映射变量(字典参数) |
m.n | m 是显示的最小总宽度,n 是小数点后的位数 |
11. 进制
11.1. 进制的表示
- 二进制
0b
开头 - 八进制
0o
开头 - 十六进制
0x
开头
11.2. 进制转换
- hex(x)
将一个整数转换为一个十六进制字符串
- oct(x)
将一个整数转换为一个八进制字符串
- bin(x)
整型转为二进制字符串
- int(x,base)
将字符串,转为指定进制(base)
x = '21'
x = int(x,8) #转为 8 进制
print(x)
#结果为 17
y = 'abc'
y = int(y,16) #转为 16 进制
print(y)
#结果为 2748
12. 运算符
12.1. 赋值运算符
=
x,*y = 1,3,4,5,6 # * 设置y的长度可变
print(y)
#结果是 [3,4,5,6]
12.2. 算术运算符
- 除
/
- 乘
*
- 减
-
- 加
+
- 取余
%
- 幂次
**
//
返回商的整数部分,向下取整,如,5//2
,得2
()
提高运算优先级
12.3. 关系运算符
>
- ` < `
>=
- ` <= `
!=
==
比较内存地址
12.3.1. 字符串使用关系运算符
- 数字和字符串做
==
运算,结果是 false - 数字和字符串做除了
==
以外的逻辑运算时,会直接报错 - 两个字符串进行比较,会将每个字符都转换成对应的ASCII编码,然后逐一进行对比
x = 'abc'
y = 'b'
if y>=x:
print('大')
12.4. 逻辑运算符
and
只要有一个运算数是False,结果就是False
只有所有的运算数都为True时,结果才是True
做取值运算时,取第一个为False的值,如果所 有的值都为True,取最后一个值
or
只要有一个运算数是True,结果就是True
只有所有的运算数都为False时,结果才是 False
做取值运算时,取第一个为True的值,如果所 有的值都为False,取最后一个值
not
取反
12.5. 成员运算符
用来判断一个东西(比如变量)是不是在另一个范围(比如列表/字典/元组)里面,若是返回True 否则返回False
- in
- not in
12.6. 身份运算符
- is
判断两个对象是否是同一个对象
12.7. 布尔类型
- True
- False
12.8. 位运算符
按位运算符是把数字看作二进制来进行计算的
&
按位与
两个相应位都为1,则该位的结果为1,否则为0
a = 0b110
b = 0b111
print(a&b)
#结果为 6
|
按位或
两个相应位相同为0,不同为1
a = 0b110
b = 0b111
print(a|b)
#结果为 7
^
按位异或
两个相应位相异时,结果为1,否则为 0
a = 0b110
b = 0b111
print(a^b)
#结果为 1
~
按位取反
对数据的每个二进制位取反,把1变为0,把0变为1
~x
类似于 -x-1
b = 0b111
print(~b)
#结果为 -8
<<
左移动运算
运算数的各二进位全部左移若干位,由 <<
右边的数字指定移动的位数,高位丢弃,低位补0
b = 0b1
print(b<<3)
#结果为 8
>>
右移动运算
运算数的各二进位全部右移若干位,由 >>
左边的数字指定移动的位数
b = 0b100
print(b>>2)
#结果为 1
13. 字符串
13.1. 表示方式
- 使用
'
或"
来创建字符串 - 三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符
13.2. 转义
python用反斜杠\
转义字符
\ (在行尾时) |
续行符 |
---|---|
\\ |
反斜杠符号 |
\' |
单引号 |
\" |
双引号 |
\a |
响铃 |
\b |
退格(Backspace) |
\e |
转义 |
\000 |
空 |
\n |
换行 |
\v |
纵向制表符 |
\t |
横向制表符 |
\r |
回车 |
\f |
换页 |
\oyy |
八进制数,yy代表的字符,例如:\o12代表换行 |
\xyy |
十六进制数,yy代表的字符,例如:\x0a代表换行 |
\other |
其它的字符以普通格式输出 |
13.3. 索引
s[i]
-
返回s中的第i个元素,i是序列的序号
-
正下标正向找,负下标逆向找
13.4. 切片
s[start:end:step]
-
返回序列s中第start到end-1 以step 为步长的元素子序列
-
step若为负数,表示倒数(倒数是从第0个开始的)
-
start和end若为负数,表示从右边数
-
倒序
y = s[::-1]
-
倒数第4个 到 倒数第1个
y = s[-4:-1]
-
从下标为7的元素开始包含下标为7的元素,倒着取到下标为2的元素不包括下标为2的元素
s[7:2:-1]
注:切片时必须在最后字符后再加1,因为python只会截取到最后字符的前一个字符
13.5. 常用方法
获取长度
len()
查找
-
find()
查找指定内容在字符串中是否存在,如果存在就返回该内容在字符串中第一次出现的开始位置索引值,如果不存在,则返回-1
S.find(sub[, start[, end]])
-
index 跟find()方法一样,只不过,未找到时,会报异常
-
rfind 是从右边开始查找的
-
rindex 是从右边开始查找的
-
判断
-
startswith 判断字符串是否以指定内容开始
-
endswith 判断字符串是否以指定内容结束
-
isalpha 判断字符串是否是纯字母
-
isdigit 判断一个字符串是否是纯数字
-
isalnum 判断是否由数字和字母组成
-
isspace 只包含空格,则返回 True,否则返回 False
出现的次数
count()
替换
replace()
s.replace('被替换的','替换的')
切割字符串
如果 maxsplit 有指定值,则仅分隔 maxsplit + 1 个子字符串
s.split('分割字符',maxsplit)
s.split('-',2)
-
split 以指定字符串为分隔符切片,返回的结果是一个列表
-
rsplit 从右往左分隔
-
splitlines 按照行分隔,返回一个包含各行作为元素的列表
-
partition 把字符串分割成三部分,str前,str和str后,三部分组成一个元组
-
rpartition 从右边开始
大小写
-
capitalize 第一个单词的首字母大写
-
title 每个单词的首字母大写
-
lower 所有都变成小写
-
upper 所有都变成大写
空格处理
-
ljust
返回指定长度的字符串,并在右侧使用空白字符补全(左对齐)
str = 'hello' print(str.ljust(10))
-
rjust
返回指定长度的字符串,并在左侧使用空白字符补全(右对齐)
-
center
返回指定长度的字符串,并在两端使用空白字符补全(居中对齐)
-
lstrip
删除字符串左边的空白字符
-
rstrip
删除字符串右边的空白字符
-
strip
删除字符串两边的空白字符
字符串拼接
把参数进行遍历,取出参数里的每一项,然后再在后面加上字符串
S.join(iterable)
作用:可以把列表或者元组快速的转变成为字符串,并且以指定的字符分隔
x = '-'
print(x.join(['abc','dcdf']))
#结果是 abc-dcdf
13.6. 字符串运算符
下表实例变量a值为字符串”Hello”,b变量值为”Python”
操作符 | 描述 | 实例 |
---|---|---|
+ |
字符串连接 | a + b 输出结果: HelloPython |
* |
重复输出字符串 | a*2 输出结果:HelloHello |
in |
如果字符串中包含给定的字符返回 True | H in a 输出结果 1 |
not in |
如果字符串中不包含给定的字符返回 True | M not in a 输出结果 1 |
r、R |
原生字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。原始字符串除在字符串的第一个引号前加上字母”r”(可以大小写)以外,与普通字符串有着几乎完全相同的语法 | print r'\n' 输出 \n 和 print R'\n'输出 \n |
13.7. 字符集
13.7.1. 字符和编码相互转换
- chr(x) 将一个ASCII转换为一个字符
- ord(x) 将一个字符转换为它的ASCII值
13.7.2. 编码规则
按照一定的编码规则对Unicode数字进行计算,得出新的编码。在中国常用的字符编码有 GBK,Big5,utf8三种编码规则
- encode方法
可以将字符串按照指定的编码格式转换为二进制
- decode方法
可以将一个二进制数据按照指定的编码格式转换成为字符串
x = b'\xe4\xbd\xa0'
print(x.decode('utf-8'))
- Unicode 字符串
引号前小写的”u”表示这里创建的是一个 Unicode 字符串
s=u"hello word"
-
默认字符串是Unicode类型,该类型字符串只能保存在内存中
-
bytes类型字符串,可以保存在磁盘和网络间数据传输
-
字符串从Unicode到bytes,需要编码:
str.enconde("utf-8")
-
字符串从bytes到Unicode,需要解码:
str.decode("utf-8")
13.8. 格式化输出
%
占位符,格式化一个字符串
a = 16
b = 'zhao'
print('my age is %d my name is %s'%(a,b))
#结果为 my age is 16 my name is zhao
{}
占位符,格式化一个字符串
{}
中什么都不写,会读取后面的内容,一一对应填充
print('my name is {} my age is {}'.format('123','456'))
#结果为 my name is 123 my age is 456
{数字}
数字就是值的下标(从0开始)
print('my name is {1} my age is {0}'.format('123','456'))
#结果为 my name is 456 my age is 123
{变量名}
print('my name is {name} my age is {age}'.format(name = '123',age = '456'))
#结果为 my name is 123 my age is 456
{数字}
和{变量}
混合使用
{}
和列表使用
使用*列表名
传参,{}
中什么都不填
a = [1,5,'bv']
print('my name is {} my age is {}'.format(*a))
#结果为 my name is 1 my age is 5
{}
和字典使用
使用**字典名
传参,{}
中填写字典中的键名
b = {'name':'zhao','age':16,'high':180}
print(*b)
#结果为 name age high
print('my name is {name} my age is {age}'.format(**b))
#结果为 my name is zhao my age is 16
13.9. 拆包
*
加一个序列(列表、元组等)表示拆包,即将一个数据拆成多个数据
a = (1,2,3,5)
print('my name is {} my age is {}'.format(*a))
#结果是 my name is 1 my age is 2
print(a)
#结果是 (1, 2, 3, 5)
print(*a)
#结果是 1 2 3 5
14. 列表(list)
- 格式
[]
- 列表的数据项不需要具有相同的类型,无论那是字符、字符串或者是另个列表
- 是有序的
- 索引从0开始计数
14.1. 切片
- 格式:
[start:end:step]
,第一个参数,是开始切割的位置,第二个参数,是结束切割的位置,第三个参数,是步长 - 倒序:
[::-1]
14.2. 列表运算符
+
将两个列表合并
14.3. 列表推导式
指的是轻量级循环创建列表
数字型
a=[i for i in range(20) if i%2==0]
#语法,我们使用了一个临时声明的变量x,x后面跟了一个for循环,使用range迭代返回的每一个值。这些东西都被放进了列表里
字符型
b=['NAme','Is']
b=[x.lower() for x in b]
14.4. 列表的复制
-
直接使用
=
,得到的两个列表指向同一个地址 -
copy()方法
得到的两个列表指向不同的地址
- copy模块
- 浅拷贝
- 深拷贝
14.5. 列表的遍历
enumerate()
带下标的遍历
test = [84,55,12,2]
en = enumerate(test)
for i in en:
print(i)
#结果是
(0, 84)
(1, 55)
(2, 12)
(3, 2)
for i,e in en:
print('第%d个元素是%d'%(i,e))
#结果是
第0个元素是84
第1个元素是55
第2个元素是12
第3个元素是2
14.6. 修改列表元素
通过遍历整个列表,修改值
num =range(5)
for item in num:
item = item*2
# 以上代码无法修改列表中的元素,因为原因item 的id(地址) 已经不是原来的id(地址)
正确方法,使用带下标的遍历
num = range(5)
for i, item in enumerate(num):
num[i] =num[i]*2
14.7. 常用方法
将元组转换为列表
list(seq)
添加元素
- append()
接收一个参数。把接收到的参数放在列表的末尾
a=['a','d','w']
a.append('q')
a.append(1)
#结果为['a', 'd', 'w', 'q', 1]
- insert(index,object)
接收两个参数,index参数表示在列表的哪个索引位置上进行插入,object表示要插入的值
a=['a','d','w']
a.insert(2,'1')
#结果为['a', 'd', '1', 'w']
- extend(seq)
在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
a = [1,2,3]
b = [4,5,6]
a.extend(b)
print(a)
#结果为 [1, 2, 3, 4, 5, 6]
删除元素
- remove()
删除特定的值(列表中第一次出现的),并不能根据我们给定的索引进行删除
a=['a','d','w','a','g','a']
a.remove('a')
#结果为['d', 'w', 'a', 'g', 'a']
- del()
删除指定索引位的值
a=['a','d','w']
del(a[2])
#结果为['a', 'd']
- pop()
移除列表中指定索引位的值,并且返回该元素的值,默认删除最后一个元素
- clear()
清空一个列表
查询元素
运算符 in
列表元素个数
len()
找最大最小值
- max()
- min()
统计某个元素在列表中出现的次数
count()
从列表中找出某个值第一个匹配项的索引位置
index()
元素反转
reverse()
排序
- sorted()
排序内置函数,不会改变原有数据,而是排序后返回一个有序的列表
- sort(cmp=None, key=None, reverse=False)
对原列表进行排序,reverse=False正序排,reverse=True逆序排
key的参数类型是函数,需要传递参数key来确定排序规则
#对列表中的字典元素进行排序,因为字典有多个参数,那么根据哪一个参数进行排序呢??
student = [
{'name':'zhangsan','age':14,'score':98},
{'name':'lier','age':17,'score':68},
{'name':'zhaoshi','age':19,'score':78}
]
def foo(a): #可以打印,看一下a的值
return a['age'] #通过返回值告诉sort排序规则,这里是按照age排序
student.sort() #直接进行排序会报错:TypeError: '<' not supported between instances of 'dict' and 'dict'
print(student) #说明字典间无法直接比较,无法排序
student.sort(key=foo) #给key传一个函数,在sort函数内部会调用foo函数
print(student)
#foo函数还可以直接写在sort的参数中,student.sort(key=lambda x:x['age'])
15. 元组 (tuple)
- 格式
()
- 只能读不能写的列表
-
定义只有一个元素的元组时,要在一个元素后加逗号
a=('3',) #类型为元组 a=('3') #类型为字符
15.1. 常用方法
- tuple(seq)
将列表转换为元组
- index()
- count()
注意
元组的增删查改是基于整个元组改变的,而若想改变里面的元素,应该用列表(list)
16. 字典( dict)
- 格式
{ : }
键值对 - 字典的值可以是任意类型的数据
16.1. 字典推导式
16.2. 常用操作
-
查看元素
- 提取出字典中的值
字典名['键名']
a = {'name':'zhaoshi','age':16} print(a['name']) #结果为 zhaoshi
- .get()
提取出字典中的值
a = {'name':'value'} print(a.get('name')) #结果为 value
-
添加元素
字典名['键名'] = 添加的值
,如果这个值在字典中,不存在,那么就会新增这个元素
a = {'name':'value'}
a['age'] = 12
print(a)
#结果为 {'name': 'value', 'age': 12}
-
删除元素
- pop()
删除键名对应的键值
a = {'name':'value','age':16} b = a.pop('name') print(a) #结果为 {'age': 16}
-
popitem()
-
del
del 字典名['键名']
a = {'name':'value','age':16} del(a['name']) print(a) #结果为 {'age': 16}
del 字典名
删除整个字典
- clear()
清空整个字典
a = {'name':'value','age':16} a.clear() print(a) #结果为 {}
16.3. 常用方法
- str()
将字典以字符串表示
- .keys()
显示字典里的所有键名
a = {'name':'value','age':16}
b = a.keys()
for i in b:
print(i)
#结果为
# name
# age
- .values()
显示所有的值
a = {'name':'value','age':16}
b = a.values()
for i in b:
print(i)
#结果为
# value
# 16
- .items()
显示所有的关键字和他们的值(同时显示)
a = {'name':'value','age':16}
b = a.items()
for i,j in b:
print(i,j)
#结果为
# name value
# age 16
- update()
在字典末尾一次性追加另一个字典(用新字典扩展原来的字典)
a = {'name':'value','age':16}
c = {'test':123}
a.update(c)
print(a)
#结果为 {'name': 'value', 'age': 16, 'test': 123}
17. 集合 (set )
- 格式
{}
- 不能有重复元素
- 只读不写
- 无序
- 空集合
set()
17.1. 操作
17.1.1. 更新集合
.add(elem)
将元素 elem添加到集合中
.pop()
随机删除一个元素
.update()
A.update(B)`B拼接到A里
.remove(elem)
删除elem元素
如果元素不存在,则会发生错误
discard(elem)
如果元素不存在,不会发生错误
.clear()
清空集合
17.1.2. 联合|
与集合的OR操作其实等价的,联合符号有个等价的方法,union()
s1=set('abcdde')
s2=set([1,2,3,4,5])
s4=s1|s2
print s4
结果为{'e', 1, 2, 3, 4, 5, 'a', 'd', 'b', 'c'}
17.1.3. 交集&
与集合AND等价,交集符号的等价方法是intersection()
17.1.4. 差集-
等价方法是difference()
17.1.5. 异或^
求两集合差集的并集
18. 序列的转换
18.1. set()
18.2. list()
18.3. tuple()
18.4. eval()
称为评估函数,作用是去掉参数中最外层引号并执行剩余语句
可转换序列的类型
a = '465'
print(type(a)) # 字符串类型
print(type(eval(a))) # int类型
多被用来执行字符串里的代码
a = 'input("请输入")' #字符串
eval(a) #执行字符串里的代码
18.5. 转JSON
- 引入json模块
import json
.dumps()
方法
.dumps()
将字典、列表、集合等转换为JSON字符串
import json
person = {'name':'zhangsan','age':18}
m = json.dumps(person)
print(m)
#结果
# '{"name": "zhangsan", "age": 18}'
.loads()
方法
将JSON字符串转换为python对应的类型,字典、列表等
19. 流程控制
19.1. 条件判断
If
else
elif
如
a=int(input())
if a==1:
print('a=1')
elif a==2:
print('a=2')
else:
print('error')
19.2. 循环结构
19.2.1. 相关函数
- range()
range函数可以有三个参数,第一个参数作为下界,第二个参数作为上界,第三个参数为步长,返回一个含有数值类型的列表
如
a=range(1,10)
b=list(a)
print(b)
#结果为[1, 2, 3, 4, 5, 6, 7, 8, 9]
- len()
返回变量的长度,无论这个变量是string类型,list类型亦或是dictionary类型
19.2.2. for
一般用于循环次数可知
19.2.3. while
一般用于循环次数未知
19.2.4. 结束循环
- BREAK ,用于跳出最近的一级for或while循环
- CONTINUE,表示结束本次循环,继续执行下一次迭代
- PASS,用于那些语法上必须要有什么语句,但程序什么也不做的场合。通常我们使用pass语句来进行占位
20. 函数
20.1. 全局变量
在函数外声明的变量,可以在脚本程序的任意位置调用这个变量
20.1.1. global
用来在函数内部修改全局变量
x = 50
def func():
x = 2
print(x)
func()
print(x)
#改变的是局部变量x,外部x不受影响
def func():
global x
x = 2
print(x)
func()
print(x)
#注意:当x被定义为全局变量时,x就不能被当作形参传入函数中
20.1.2. 相关函数
内置函数
- globals() 查看全局变量
- locals() 查看局部变量
20.2. 局部变量
在函数里声明的变量,只能在函数内部被调用而不能在函数外部调用
注:如果在函数范围内定义了具有相同名称的变量,那么它将仅打印函数内给出的值而不是全局值
20.3. 函数名
函数名相当于变量,指向函数体中的代码
def a():
print("输出a");
b = a; #相当于给函数起个别名
b(); #结果是 输出a
20.4. 函数的回调
把该函数当作参数传给另一个函数
#运算 a b
def calc(a,b,fun):
c = fun(a,b)
return c
def add(a,b):
return a + b
def jian(a,b):
return a - b
#把函数名当作参数传递给另一个函数,就可以在另一个函数中调用
calc(5,2,add) #调用加法函数
calc(5,2,jian) #调用减法函数
20.5. def声明函数
20.5.1. 调用函数
函数名(参数)
def greet():
pass
greet();
20.6. 传参
20.6.1. 缺省参数
形参中默认有值的参数
有默认值的参数,一定要位于参数列表的最后面
def func(a, b=5)
#是有效的,但是
def func(a=5, b)
#是无效的
20.6.2. 关键字传参
此方法,不必担心参数的顺序
def func(x=2,y=3):
z=x+y
print(z)
func(y=1,x=3)
#尽管函数定义中,x在y之前定义,我们仍然可以在x之前指定参数y的值。
20.6.3. 传多个参数
将多个数据捆绑到一个列表、字典、元组中等,传入函数中
#求多个数的和
def add(num):
x = 0
for i in num:
x+=i
return x
num = [1,2,3,4,5]
print(add(num))
20.6.4. 可变参数
可变参数允许传入在函数声明时,没有命名的参数
*args
表示可变位置参数(一般的参数),多出来的参数会以元组的形式保存到args里
def add(a,b,*args):
print('arg = {}'.format(args))
add(1,2,4,5,6,7)
#结果是 arg = (4, 5, 6, 7)
**kwargs
表示可变关键字参数,多出来的参数会以字典的形式保存到kwargs里
def add(a,b,**kwargs):
print('kwargs = {}'.format(kwargs))
add(1,2,x = 4,y = 5)
#结果是 kwargs = {'x': 4, 'y': 5}
20.6.5. 参数的顺序
一般参数,*args,缺省参数,**kwargs
20.7. return
如果一个函数没有返回值,它的返回值就是None
20.7.1. 返回多个值
将多个数据捆绑到一个列表、字典、元组中等
def test(a,b):
x = a//b
y = a%b
return [x,y]
return x,y #默认返回的是元组
result = test(10,3)
print(result[0],result[1])
20.8. 函数的文档说明
三个双引号
def add():
"""
说明内容
"""
20.9. lambda匿名函数
- 格式: lambda 参数 :参数的运算式
- lambda表达式必须被赋值给某个变量才能发挥作用
- 作用:用来表达一个简单的函数,调用次数很少
20.9.1. 调用函数
- 给函数命名(使用较少)
f=lambda x,y : x+y
print(f(1, 2)) #计算两数之和,输出:3
- 函数回调
def calc(a,b,fun):
c = fun(a,b)
return c
x1 = calc(5,2,lambda x,y:x+y) #计算加法
x2 = calc(5,2,lambda x,y:x-y) #计算减法
x3 = calc(5,2,lambda x,y:x/y) #计算除法
print(x1)
20.9.2. lambda操作符
- fliter()
对可迭代对象进行过滤
可以被用来过滤原有的list,并把过滤结果放进新的list里。filter接受两个参数,第一个是lambda表达式提供的过滤条件,第二个是要进行过滤的现有列表。最后,filter返回一个符合条件的列表类型
如
from functools import fliter
a=[x for x in range(1,10)]
b=filter(lambda i:i%2==0,a)#将列表中符合条件的值,过滤出来
print(b)
#结果为[2, 4, 6, 8]
- map()
可以同时对list里的所有元素进行操作,并以列表方式给出返回值
如
from functools import map
a=[x for x in range(1,10)]
b=map(lambda i:i**2,a)#将列表里的内容都平方
print(b)
#结果为[1, 4, 9, 16, 25, 36, 49, 64, 81]
- reduce()
可以对列表顺序执行算术运算
from functools import reduce
a = [1, 4, 9, 16, 25, 36, 49, 64, 81]
b = reduce(lambda x,y:x+y,a)#将列表里的内容相加,具体过程:x = 1,y = 4;x = 1 + 4,y = 9;x = 1+ 4 + 9..
print(b)
#结果为[1, 4, 9, 16, 25, 36, 49, 64, 81]
高级操作
#对列表中字典元素的年龄进行求和,因为字典有多个参数,那么如何让年龄求和呢??
from functools import reduce
student = [
{'name':'zhangsan','age':14,'score':98},
{'name':'lier','age':17,'score':68},
{'name':'zhaoshi','age':19,'score':78}
]
def bar(x,y):
b = reduce(bar,student,0)#定义一个bar函数实现,列表内字典元素的相加,并给x一个初始值 0
print(b) #结果为 50
20.10. 常用内置函数
- dir()
列出对象的所有方法
- isinstance
判断一个对象是否由一个类创建出来
- issubclass
判断一个类是否为另一个类的子类
- iter
获取可迭代对象的迭代器
- sorted
排序
20.11. 高阶函数
- 将函数作为另一个函数的返回值
def old():
print('我被old调用了')
return old
def new():
print('我被new掉调用了')
# return old()
return old #将函数名作为返回值
a = new()
a() #调用返回的函数
- 函数中定义函数
def outer():
m = 10
def inner():
n = 90
print('我是inner')
print('我是outer')
return inner #返回函数名
outer() #调用outer函数
outer()() #先调用outer后调用inner
- 闭包
在内部函数里对外部函数的变量进行调用
在内部函数里对外部函数的变量进行修改,需要用nonlocal
声明
def outer():
m = 10
print(m)
def inner():
nonlocal m #nonlocal,进行声明
m = 50 #修改外部函数变量的值
print(m)
if True:
inner()
print(m) #前面如果不用nonlocal声明,这里将打印 10而不是50
21. 装饰器
用@
声明一个装饰器
给某个函数加装饰器,在该函数的前一行,声明装饰器即可
import time
def cal_time(fun):
print('外部函数被调用')
def inner():
start = time.time()
fun()
end = time.time()
print('本次程序耗时',end-start)
return inner
@cal_time #相当于cal_time(demo)
#装饰器
#第一件事,调用cal_time
#第二件事,把装饰器的函数传递给fun
#第三件事,再次调用demo时,执行的已经不是以前的demo
def demo():
x = 0
for i in range(1,100000):
x+=i
print('demo被执行')
demo() #执行的已经不是以前的demo,而是cal_time函数内的inner函数,通过inner函数来调用demo函数
21.1. 被修饰的函数无参数
def check_time(action):
print('check_time被调用')
def do_action():
action()
print('do_action被调用')
return do_action
@check_time #会调用check_time
def go_to_bad():
print('上床睡觉')
go_to_bad() #实际上调用的是do_action
21.2. 被修饰的函数有参数
def check_time(action):
print('check_time被调用')
def do_action(name):
action(name)
print('do_action被调用')
return do_action
@check_time
def go_to_bad(name):
print('{}上床睡觉'.format(name))
go_to_bad('张三')
21.3. 被修饰的函数有不定长参数
def check_time(action):
print('check_time被调用')
def do_action(*args):
action(*args)
print('do_action被调用')
return do_action
@check_time
def go_to_bad(*args):
sum = 0
for x in args:
sum +=x
print(sum)
go_to_bad(1,2,3,4,5)
21.4. 装饰器中的return
22. 模块(module)
- python里,一个
.py
文件就是一个模块 .py
文件的命名必须遵守规则:由字母、数字、下划线构成,不能以数字开头
22.1. 导入模块
import 模块名
直接导入一个模块
from 模块名 import 函数名
导入一个模块里的方法或变量
from 模块名 import *
导入这个模块的所有方法和变量(不是所有),使用该方法导入一个模块里所有的内容时,本质上是去查找这个模块的 __all__
属性,将 __all__
属性里声明的所有内容导入。如果这个模块里没有设置 __all__
属性,此时才会导入这个模块里的所有内容
import 模块名 as 别名
导入一个模块并为其起别名
from 模块名 import 函数名 as 别名
22.2. pip
- pip install 模块名
下载第三方模块
- pip uninstall 模块名
卸载第三方模块
- pip freeze
列出当前环境安装模块名和版本号
- pip freeze > filename
将安装的模块名和版本号重定向输出到指定的文件
- pip install -r filename
读取文件中的模块名和版本号并安装。该方法常用于将代码部署到服务器时,给服务器的python安装模块
- pip install 模块名 -i 源的地址
(临时的)更改模块的下载源
- 永久更改源地址
在当前用户目录下(C:\Users\用户名
)创建一个pip的文件夹,然后再在文件夹里创建pip.ini文件并输入以下内容
[global]
index-url=https://pypi.douban.com/simple
[install]
trusted-host=pypi.douban.com
#国内镜像
#阿里云 https://mirrors.aliyun.com/pypi/simple/
#中国科技⼤大学 https://pypi.mirrors.ustc.edu.cn/simple/
#豆瓣(douban) https://pypi.douban.com/simple/
#清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
#中国科学技术大学 https://pypi.mirrors.ustc.edu.cn/simple/
22.3. 模块里的私有成员
模块里以一个下划线 _
开始的变量和函数,是模块里的私有成员,当模块被导入时,以 _
开头的变量默认不会被导入。但是它不具有强制性,如果一个代码强行使用以 _
开头的变量,有时也可以。但是强烈不建议这样使用,因为有可能会出问题
22.4. __all__
一个存放模块变量和方法的列表
22.5. __name__
Python中,当直接运行一个py文件时,这个py文件里的 __name__
值是 __main__
,当这个py文件被当作模块导入时 __name__
的值是文件名 ,据此可以判断一个py文件是被直接执行还是以模块的形式被导入。
if __name__ == '__main__':
print 'This program is being run by itself'
else:
print 'I am being imported from another module'
23. 包
一般把 Python 里的一个代码文件夹称为一个包,并在包里创建 __init__.py
文件
导包
以项目根目录为准,输入目标模块 或 包的路径: from spiders._tools import xxx
24. python面向对象编程
可以使用dir
内置函数来查看一个对象里的方法
24.1. 定义类
方法里的第一个参数必须是self
class 类名:
def 方法1(self,参数列表):
pass
def 方法2(self,参数列表):
pass
24.2. 创建实例对象
对象变量名 = 类名()
#如
a = A()
class People:
def __init__(self,x,y,z):
self.name = x
self.age = y
self.height = z
def run(self):
print("正在跑步")
def eat(self):
print("正在吃东西")
def __str__(self):
return '自动调用print'
s1 = People('小明',16,180) #这段代码做了
#调用__new__方法用来申请内存空间
#调用__init__方法,并让self指向申请好的那段内存空间,填充数据
#让s1也指向那段内存空间
print(s1)
#结果:自动调用print
24.3. self的使用
- 给对象添加属性
class People:
def __init__(self,x,y,z):
self.name = x #添加属性
self.age = y
self.height = z
- python支持动态属性,当一个对象创建好了以后,直接使用
对象.属性名 = 属性值
就可以很方便的给对象添加一个属性。但是,不建议使用这种方式给对象添加属性
tom = Cat()
tom.name = 'Tom' # 可以直接给 tom 对象添加⼀一个 name 属性
24.3.1. self概念
哪个对象调用了方法,方法里的self
指的就是谁。通过self.属性名
可以访问到这个对象的属性。通过self.方法名()
可以调用这个对象的方法
24.4. 魔术方法
- 特点
两个下划线开始,两个下划线结束的方法
魔术方法在恰当的时候就会被激活,自动执行
__init__
方法
该方法在创建对象时,会默认被调用
方法里的self参数,在创建对象时不需要传递参数,python解释器会把创建好的对象引 用直接赋值给self
在类的内部,可以使用self来使用属性和调用方法。在类的外部,需要使用对象名来使用属性和调用方法
如果有多个对象,每个对象的属性是各自保存的,都有各自独立的地址
方法是所有对象共享的,只占用一份内存空间,方法被调用时会通过self来判断是哪个对象调用了实例方法
__del__
方法
该方法在删除对象时,会默认被调用
__str__
方法
返回对象的描述信息,使用print()
函数打印对象时,其实调用的就是这个对象的 __str__
方法
如果想要修改对象的输出的结果,可以重写 __str__
方法
__repr__
方法
__repr__
方法和 __str__
方法功能类似,都是用来修改一个对象的默认打印内容。
在打印一个对象时,如果没有重写 __str__
方法,它会自动来查找 __repr__
方法。
如果这两个方法都没有,会直接打印这个对象的内存地址。
如果这两个方法都有,会调用__str__
方法
__call__
对象后面加括号,触发执⾏
class People:
def __init__(self,x,y,z):
self.name = x
self.age = y
self.height = z
def run(self):
print("正在跑步")
def eat(self):
print("正在吃东西")
def __call__(self):
print("__call方法被调用")
s1 = People('小明',16,180)
s1() #调用__call__方法
class People:
def __init__(self,x,y,z):
self.name = x
self.age = y
self.height = z
def run(self):
print("正在跑步")
def eat(self):
print("正在吃东西")
def __call__(self,*args,**kwargs):
print("__call方法被调用")
print("{}\n".format(args))
print("{}\n".format(kwargs))
fun = kwargs['fn']
print(fun(args[0], args[1]))
s1 = People('小明',16,180)
s1(1,2,fn = lambda x,y:x+y)
__eq__
==
默认调用对象的__eq__
方法,获取该方法的返回值。若__eq__
方法不重写,则默认比较内存地址
身份运算符is
用来判断两个对象是否是同一个对象
24.5. 对象的内置属性
__slots__
属性
防止通过动态属性,直接给对象添加属性
class Person(object):
__slots__ = ('name', 'age') #限制了动态属性
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('张三', 18)
p.name = '李李四'
p.height = 180 #报错
# 对象p只能设置name和age属性,不能再动态添加属性 p.height = 180
__doc__
表示类的描述信息,获取类中的文档说明'''中的内容'''
,可以类名.__doc__
也可以__对象名.__doc__
调用
class Person:
'''一些介绍'''
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('张三', 18)
print(p.__doc__) #结果:一些介绍
__module__
表示当前操作的对象在那个模块
class Person:
'''一些介绍'''
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('张三', 18)
print(p.__module__) #结果是 __main__
__class__
表示当前操作的对象的类是什么
class Person:
'''一些介绍'''
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('张三', 18)
print(p.__class__) #结果是 <class '__main__.Person'>
__dict__
以字典的形式,显示对象所有的属性和方法
class Person:
'''一些介绍'''
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('张三', 18)
print(p.__dict__) #结果是 {'name': '张三', 'age': 18}
24.6. 类属性和对象属性
- 类属性可以通过类对象或者实例对象访问
class Person:
number = '06' #类属性
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('张三', 18)
print(p.number) #通过实例对象访问类属性
print(Person.number) #通过类对象访问类属性
- 如果有同名实例属性和类属性,实例对象会优先访问实例属性
class Person:
number = '06' #类属性
def __init__(self, name, age,number):
self.name = name
self.age = age
self.number = number #同名属性
p = Person('张三', 18,'08')
print(p.number) #结果为08,实例对象会优先访问实例属性
print(Person.number) ##结果为06
- 类属性只能通过类对象修改,不能通过实例对象修改
class Person:
number = '06'
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('张三', 18)
p.number = '01'
print(Person.number) #结果为06
Person.number = '01'
print(Person.number) #结果为01
- 类属性也可以设置为私有,前边添加两个下划线
24.7. 私有属性和方法
对象的属性或者方法只可以在对象的内部使用,在外部不能被访问
24.7.1. 定义
在定义属性或方法时,在属性名或者方法名前增加两个下划线 __
,定义的就是私有属性或方法
24.7.2. 访问私有
- 直接访问
在私有属性名或方法名前添加_类名
class Person:
def __init__(self, name, age):
self.__money = 800 #私有属性
self.name = name
self.age = age
p = Person('张三', 18)
print(p._Person__money) #直接访问私有属性
- 定义方法访问
可以通过定义get
和 set
方法来实现访问私有
class Person:
def __init__(self, name, age):
self.__money = 800
self.name = name
self.age = age
def get(self):
return self.__money
def set(self,money):
self.__money = money
p = Person('张三', 18)
print(p.get()) #结果是 800
p.set(2)
print(p.get()) #结果是 2
24.8. 类方法
- 对象方法可以使用
实例对象名.方法(参数)
调用,该方法不需要为self
传参,会自动为self
传参
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def demo(self,number): #类方法
print(self.name + '学号是' + number)
p = Person('张三', 18)
p.demo('01') #通过对象调用
#结果 张三学号是01
- 对象方法还可以使用
类名.方法(参数)
调用,该方法不会自动为self
传参,需要手动指定self
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def demo(self,number):
print(self.name + '学号是' + number)
p = Person('张三', 18)
Person.demo(p,'02') #通过类调用
#结果 张三学号是02
24.9. 继承
- 在Python中,继承可以分为单继承、多继承和多层继承
- 定义类时,在类名的括号后面传入父类的类名,表示子类继承父类
class Animal:
def __init__(self):
pass
'''动物类'''
def sleep(self):
print('正在睡觉')
class Dog(Animal): #继承于Animal类
'''Dog类继承于Animal类'''
def __init__(self):
pass
dog = Dog()
dog.sleep()
24.10. 多态
25. 文件操作
25.1. 手动文件I/O操作
25.1.1. 写文件
file = open('路径','w')
file.write('内容')
file.close()
25.1.2. 读文件
file = open('路径','r')
file.read()
file.close()
注意:定要记得把文件关上。如果不关闭文件,就会导致一些错误,文件也可能会被损坏。
25.2. 自动文件I/O操作
用with关键字和as关键字来打开和关闭文件。会自动关闭文件,不需要close()函数
25.2.1. 写文件
with open('路径','w') as 变量名:
变量名.write('内容')
25.2.2. 读文件
with open('路径','r') as 变量名:
变量名.read()
25.3. 相关函数
open()
open(file,mode,encoding)
- file 文件路径(相对或者绝对路径)
windows中使用\
分隔路径,但python中\
表示转义符
python中可以使用\\
或/
分割路径,也可以使用r'路径'
表示(即在路径前加r)
- encoding 打开文件时的编码方式
windows中默认使用gbk
编码读写文件
-
mode 文件打开模式
r
只读(默认模式),如果文件不存在会报错
w
打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件
a
追加,新内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入
r+
打开一个文件用于读或写
w+
打开一个文件用于读或写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件
a+
打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写
rb
以二进制方式读文件
wb
以二进制方式写文件,如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件
ab
追加,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入
rb+
以二进制格式打开一个文件用于读写
wb+
以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件
ab+
以二进制格式打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写
read()
read(num),num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据,返回的数据类型是一个字符串
readline()
每次读出一行内容,包括 \n
字符
#方法1
file = open("foo.txt")
while True:
content = file.readline()
print(content)
if content =='':
break
file.close()
#方法2
for line in open('文件名')
print(line)
readlines()
读取整个文件所有行,保存在一个列表中,每行作为一个元素
strip()
使用strip去掉每行结束的\n
for line in file.readlines():
line=line.strip('\n')
write()
写数据,只能写入字符串和二进制
writelines()
写行数据,只能写入字符串和二进制
将多个值同时写入一行中
25.4. 文件指针
- tell()
- seek()
25.5. CSV文件的读写
Comma-Separated Values,中文叫逗号分隔值或者字符分割值,其文件以纯文本的形式存储表格数据。可以把它理解为一个表格,只不过这个表格是以纯文本的形式显示的,单元格与单元格之间,默认使用逗号进行分隔,每行数据之间,使用换行进行分隔
25.5.1. CSV文件的写⼊
使用csv模块
import csv
# 以写⼊入⽅式打开⼀个csv⽂件
file = open('test.csv','w')
# 调⽤用writer⽅法,传⼊csv⽂件对象,得到的结果是⼀个CSVWriter对象
writer = csv.writer(file)
# 调⽤CSVWriter对象的writerow⽅法,⼀行一行的写⼊数据
writer.writerow(['name', 'age', 'score'])
# 还可以调⽤writerows⽅法,⼀次性写⼊多行数据
writer.writerows([['zhangsan', '18', '98'],['lisi', '20', '99'], ['wangwu', '17', '90'], ['jerry', '19', '95']])
file.close()
25.5.2. CSV文件的读取
import csv
# 以读取⽅式打开⼀个csv⽂件
file = open('test.csv', 'r')
# 调⽤csv模块的reader⽅法,得到的结果是⼀个可迭代对象reader = csv.reader(file)
# 对结果进行遍历,获取到结果里的每⼀⾏数据
for row in reader:
print(row)
file.close()
25.6. 内存中写入数据
StringIO和BytesIO
25.7. 序列化和反序列化
通过文件操作,我们可以将字符串写入到一个本地文件。但是,如果是一个对象(如列表、字典、元组等),就无法直接写入到一个文件里,需要对这个对象进行序列化,然后才能写入到文件里
25.7.1. JSON模块
JSON的本质是字符串
反序列化
- json.loads()
将已编码的 JSON 字符串解码为 Python 对象
- json.load()
读取文件,把读取的JSON内容解码为 Python 对象
序列化
- json.dumps()
将 Python 对象编码成 JSON 字符串,不会将数据保存到文件里
- json.dump()
json.dump(数据,file)
将 Python 对象编码成 JSON 字符串,同时将数据保存到指定文件里
import json
a = {'name':'zhaoshi','age':16}
file = open('test.txt','wb')
file.write(pickle.dumps(a))
file.close()
25.7.2. pickle模块
将对象转换成为二进制(只有python能识别的二进制)
反序列化
- pickle.loads()
将二进制解码为 Python 对象
- pickle.load()
读取文件,把读取的二进制内容解码为 Python 对象
序列化
- pickle.dumps()
将 Python 对象编码成二进制,不会将数据保存到文件里
- pickle.dump()
json.dump(数据,file)
将 Python 对象编码成二进制,同时将数据保存到指定文件里
import pickle
a = {'name':'zhaoshi','age':16}
file = open('test.txt','wb')
file.write(pickle.dumps(a))
file.close()
file = open('test.txt','rb')
x = file.read()
print(pickle.loads(x))
25.7.3. 对比
- pickle
pickle序列化是将对象按照一定的规则转换成为二进制保存,它不能跨平台传递数据
pickle的序列化会将对象的所有数据都保存
- json
将对象转换成为字符串,json就是用来在不同平台间传递数据的
不是所有的对象都可以直接转换成为一个字符串
python | JSON |
---|---|
dict | object |
list、tuple | array |
str | string |
int、float | number |
True | true |
False | false |
None | null |
26. 异常处理
增加程序的稳定性(健壮性),我们应该尽可能的考虑可能发生错误的点以及用户的使用方式,以使得程序不会轻易的崩溃
26.1. try+except
except可以专门处理单一的错误或异常,也可以处理一组在元组中的错误/异常。如果没有给出错误或异常的名称,它会处理所有的错误和异常
try:
可能会出现异常的代码块
except 异常的类型:
出现异常以后的处理理语句
26.2. try+except+else
如果没有捕获到异常,那么就执行else中的代码
try:
num = 100
print(num)
except NameError as e:
print('产⽣生错误了了:%s'%e)
else:
print('没有捕获到异常,真⾼高兴')
26.3. try+finally
在程序中,如果一段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用finally,比如 文件关闭,释放锁,把数据库连接返还给连接池
如果函数里有finally,finally里的返回值会覆盖之前的返回值
def div(a,b):
try:
x = a/b
except:
return 'error'
else:
return x
finally:
return '没有捕获到异常,真⾼兴'
print(div(1, 2))
#结果为 没有捕获到异常,真⾼兴
26.4. 自定义异常
用raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是Error或Exception类的子类
常用
except Exception as e:
高级
class ShortInputException(Exception):
'''⾃定义的异常类'''
def __init__(self, length, atleast):
#super().__init__()
self.length = length
self.atleast = atleast
def __str__(self):
return '输入的长度是 %d,长度至少应是 %d'% (self.length, self.atleast)
def main():
try:
s = input('请输入 --> ')
if len(s) < 3:
# raise 引发一个自定义的异常
raise ShortInputException(len(s), 3)
except ShortInputException as result: # x这个变量被绑定到了错误的实例
print('ShortInputException:' % result)
else:
print('没有异常发生.')
main()
26.5. 异常获取
- str(e)
返回字符串类型,只给出异常信息,不包括异常信息的类型,如1/0的异常信息
‘integer division or modulo by zero’
- repr(e)
给出较全的异常信息,包括异常信息的类型,如1/0的异常信息
“ZeroDivisionError(‘integer division or modulo by zero’,)”
- e.message
获得的信息同str(e)
- 采用traceback模块
需要导入traceback模块,此时获取的信息最全,与python命令行运行程序出现错误信息一致。使用traceback.print_exc()
打印异常信息到标准错误,就像没有获取一样,或者使用traceback.format_exc()
将同样的输出获取为字符串。你可以向这些函数传递各种各样的参数来限制输出,或者重新打印到像文件类型的对象
注意:
在 Python 3 Exception 的 except 子句中,不支持使用逗号 ,
分隔 Exception 和 e,所以需要采用 as 关键词进行替换
#以 1/0 异常处理为例
try:
1/0
except Exception as e:
print('str(Exception):\t', e.message)
print('str(e):\t\t', str(e))
print('repr(e):\t', repr(e))
与 Python 2 Exception 类相比,Python 3 Exception 类没有 message 成员变量。针对这个问题,可以采用 sys.exc_info()
方法获取得到相关的异常信息。 sys.exc_info
方法可以获取 except 子句正在处理的异常,其返回值为一个tuple类型的三元组(exc_type, exc_value, exc_traceback)
,其中,exc_type
为获取到的异常类型;exc_value
为该异常类型对象;exc_traceback
为一个 traceback 对象,包含异常最初发生的调用栈信息。
程序中的变量 e 和 exc_value 是同一个异常类型实例对象
27. with关键字
对于系统资源如文件、数据库连接、socket 而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源,with关键字就是用来自动关闭资源的
with语句实质上是一个上下文管理器,with语句后的对象都会有__enter__()
和__exit__()
方法。在进入到上下文时,会自动调用__enter__()
方法,程序正常执行完成,或者出现异常中断的时候,都会调用__exit__()
方法
如
用with关键字打开文件
with open('路径','w') as 变量名:
28. 高级装饰器
29. 迭代器
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不能后退
29.1. 迭代对象(Iterable)
- 本质
一个具备了__iter__
方法的对象,就是一个可迭代对象
- 判断
使用 isinstance()
判断一个对象是否是 Iterable 对象
29.2. 迭代器(Iterator)
- 本质
一个实现了__iter__
方法和__next__
方法的对象,就是迭代器
- 判断
调用一个对象的__iter__
方法,或者调用iter()
内置函数,可以获取到一个可迭代对象的迭代器,然后使用isinstance()
判断一个对象是否是 Iterator 对象
30. 生成器
生成器是一类特殊的迭代器
31. 时间戳转日期
import time
# 获得当前时间时间戳
now = int(time.time())
#转换为其他日期格式,如:"%Y-%m-%d %H:%M:%S"
timeArray = time.localtime(now)
otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
print(otherStyleTime)
32. linux下的py
32.1. 代码执行
- 用python指令执行
- 用shebang,Shebang(也称为Hashbang)是一个由井号和叹号构成的字符序列
#!
,shebang符号可以在脚本内部指定解释器路径
#! /usr/bin/python
print 'hahah'
先赋予这个脚本文件执行权限
然后`./脚本名称`,即可运行