1. python3特性
- 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. 交互式编程
即直接在终端(如 cmd )中运行解释器,而不使用文件名的方式来执行文件。这种交互式的编程环境,我们也可以称之为REPL,即读取(Read)输入的内容,执行(Eval)用户输入的指令,打印(Print)执行结果,然后进行循环(Loop),Python支持交互式编程
ipython
是一个python
的交互式shell
,比默认的python shell
好用得多,支持变量自动补全,自动缩进,支持bash shell
命令,内置了许多很有用的功能和函数
4. 基础
4.1. 字符编码
概念 | 概念描述 | 举例 |
---|---|---|
字符集 | 字符的集合 | ASCII 字符集,GB2312 字符集,Unicode 字符集 |
字符编码 | 将字符集中的字符,编码为特定的二进制数 | ASCII 编码,GB2312 编码,Unicode 编码 |
Python3 的默认编码是 utf-8
UTF-8 是一种针对 Unicode 的可变长度字符编码,它是 Unicode 的实现方式之一
4.2. 输入和输出
输入(input)
返回字符串类型 input('提示信息')
同时输入多个值 a,b,c=input().split(' ')
输入a,b,c时,将a、b、c用空格隔开
如有特殊要求,可以考虑加上 eval(input())
输出(print)
print(value,sep,end)
%格式化输出
%
占位符,格式化一个字符串
a = 16
b = 'zhao'
print('my age is %d my name is %s'%(a,b))
#结果为 my age is 16 my name is zhao
| 格式符号 | 转换 |
| :——- | :————————- |
| %%
| 输出 %
号 |
| %s
| 字符串 |
| %d
| 有符号十进制整数 |
| %f
| 浮点数 |
| %c
| 字符 |
| %u
| 无符号十进制整数 |
| %o
| 八进制整数 |
| %x
| 十六进制整数(小写字母0x
) |
| %X
| 十六进制整数(大写字母0X
) |
| %e
| 科学计数法(小写e
) |
| %E
| 科学计数法(大写E
) |
| %g
| %f
和%e
的简写 |
| %G
| %f
和%E
的简写 |
{}格式化输出
{}
占位符,格式化一个字符串
{}
中什么都不写,python会按顺序填充
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
使用*序列名
传参,{}
中什么都不用填,python会自动拆包
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
格式化操作符辅助指令
符号 | 功能 |
---|---|
* | 定义宽度或者小数点精度 |
- | 用做左对齐 |
+ | 在正数前面显示加号( + ) |
<sp> |
在正数前面显示空格 |
# |
在八进制数前面显示零0 ,在十六进制前面显示0x 或者0X |
0 | 显示的数字前面填充0而不是默认的空格 |
(var) | 映射变量(字典参数) |
m.n | m 是显示的最小总宽度,n 是小数点后的位数 |
4.3. 流程控制
4.3.1. 条件判断
a=int(input())
if a==1:
print('a=1')
elif a==2:
print('a=2')
else:
print('error')
4.3.2. 循环结构
for,一般用于循环次数可知
while,一般用于循环次数未知
相关函数
- range()
range函数可以有三个参数,第一个参数作为下界,第二个参数作为上界,第三个参数为步长,返回一个含有数值类型的列表
如
a=range(1,10) b=list(a) print(b) #结果为[1, 2, 3, 4, 5, 6, 7, 8, 9]
- len()
返回变量的长度,无论这个变量是string类型,list类型亦或是dictionary类型
结束循环
-
BREAK ,用于跳出最近的一级for或while循环
-
CONTINUE,表示结束本次循环,继续执行下一次迭代
-
PASS,用于那些语法上必须要有什么语句,但程序什么也不做的场合。通常我们使用pass语句来进行占位
4.4. 变量
只要定义了一个变量,而且它有数据,那么它的类型就已经确定了,不需要开发者主动的去说明它的类型,系统会自动辨别。变量没有类型,数据才有类型
同时为多个变量赋值
x, y, z = "Orange", "Banana", "Cherry"
交换a b的值
a,b=b,a
+
号连接字符
x = "awesome"
print("Python is " + x)
*
重复多次
x= 'abc'
print(x*2)
#结果为 abcabc
4.5. 运算符
赋值运算符
=
x,*y = 1,3,4,5,6 # * 设置y的长度可变
print(y)
#结果是 [3,4,5,6]
算术运算符
-
除
/
-
乘
*
-
减
-
-
加
+
-
取余
%
-
幂次
**
-
//
返回商的整数部分,向下取整,如,5//2
,得2
()
提高运算优先级
关系运算符
-
>
-
<
-
>=
-
<=
-
!=
-
==
比较内存地址
字符串使用关系运算符
-
数字和字符串做
==
运算,结果是 false -
数字和字符串做除了
==
以外的逻辑运算时,会直接报错 -
两个字符串进行比较,会将每个字符都转换成对应的ASCII编码,然后逐一进行对比
x = 'abc'
y = 'b'
if y>=x:
print('大')
逻辑运算符
and
只要有一个运算数是False,结果就是False
只有所有的运算数都为True时,结果才是True
做取值运算时,取第一个为False的值,如果所 有的值都为True,取最后一个值
or
只要有一个运算数是True,结果就是True
只有所有的运算数都为False时,结果才是 False
做取值运算时,取第一个为True的值,如果所 有的值都为False,取最后一个值
not
取反
成员运算符
用来判断一个东西(比如变量)是不是在另一个范围(比如列表/字典/元组)里面,若是返回True 否则返回False
-
in
-
not in
身份运算符
- is
判断两个对象是否是同一个对象
位运算符
按位运算符是把数字看作二进制来进行计算的
&
按位与
两个相应位都为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
4.6. 进制的表示
- 二进制
0b
开头 - 八进制
0o
开头 - 十六进制
0x
开头
5. 常用数据类型
不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组)
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)
5.1. 数字(Number)
包括整型、浮点型、复数等
科学计数
科学计数法: 1.5 x 10^11表示为:
1.5e11 这里e和E不区分大小写
复数
复数由实数部分和虚数部分组成,实数部分和虚数部分都是浮点型,虚数部分必须有后缀j或J
print (64.375+1j) 结果为64.375+1j
5.2. 字符串(String)
用于表示文本数据,可以使用单引号、双引号或三引号来定义字符串
特点
使用'
或"
来创建字符串
三引号'''
允许一个字符串跨多行,其中可以包含换行符、制表符以及其他特殊字符
转义
python用反斜杠\
转义字符
\ (在行尾时) |
续行符 |
---|---|
\\ |
反斜杠符号 |
\' |
单引号 |
\" |
双引号 |
\a |
响铃 |
\b |
退格(Backspace) |
\e |
转义 |
\000 |
空 |
\n |
换行 |
\v |
纵向制表符 |
\t |
横向制表符 |
\r |
回车 |
\f |
换页 |
\oyy |
八进制数,yy代表的字符,例如:\o12代表换行 |
\xyy |
十六进制数,yy代表的字符,例如:\x0a代表换行 |
\other |
其它的字符以普通格式输出 |
索引
s[i]
正下标正向找,负下标逆向找
切片
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只会截取到最后字符的前一个字符
获取长度
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
字符串运算符
下表实例变量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 |
字符和编码相互转换
-
chr(x) 将一个ASCII码转换为一个字符
-
ord(x) 将一个字符转换为它的ASCII值
-
encode方法
可以将字符串按照指定的编码格式转换为二进制
- decode方法
可以将一个二进制数据按照指定的编码格式转换成为字符串
x = b’\xe4\xbd\xa0’
print(x.decode(‘utf-8’))
- Unicode 字符串
引号前小写的u
表示这里创建的是一个 Unicode 字符串
s=u”hello word”
-
字符串从Unicode到bytes,需要编码:
str.enconde("utf-8")
-
字符串从bytes到Unicode,需要解码:
str.decode("utf-8")
5.3. 列表(List)
特点
[]
用于存储一组有序的元素,可以包含不同类型的元素,通过索引访问元素
字符串和元组是不可变的,而列表是可变(mutable)的,可以对它进行随意修改。我们还可以将字符串和元组转换成一个列表,只需使用 list
函数
切片
[start:end:step]
,第一个参数,是开始切割的位置,第二个参数,是结束切割的位置,第三个参数,是步长
倒序:[::-1]
列表运算符
+
将两个列表合并
列表推导式
指的是轻量级循环创建列表
a=[i for i in range(20) if i%2==0]
我们使用了一个临时声明的变量i,i后面跟了一个for循环,迭代返回的每一个值都被放进了列表里
列表的复制
直接使用=
,得到的两个列表指向同一个地址
copy(),得到的两个列表指向不同的地址(分为深浅拷贝)
列表的遍历
enumerate(),带下标的遍历
test = [84,55,12,2]
en = enumerate(test)
for i in en:
print(i)
# (0, 84)
# (1, 55)
# (2, 12)
# (3, 2)
常用的列表方法
- index
- count
- append
- extend
- insert
- pop
- remove
- reverse
- sort
添加元素
- 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’])
5.4. 元组(Tuple)
()
类似于列表,但是元组中的元素不可修改,通常用于存储不可变的数据
创建一个空元组可以用没有包含内容的圆括号来表示
a = ()
定义只有一个元素的元组时,要在一个元素后加逗号
a=('3',) #类型为元组
a=('3') #类型为字符
常用方法
- tuple(seq)
将列表转换为元组
-
index()
-
count()
注意
元组的增删查改是基于整个元组改变的,而若想改变里面的元素,应该用列表(list)
5.5. 集合(Set)
特点
{}
用于存储一组不重复的元素,可以进行交、并、差等集合运算
只读不写
无序
空集合 set()
更新集合
.add(elem)
将元素 elem添加到集合中
.pop()
随机删除一个元素
.update()
A.update(B)`B拼接到A里
.remove(elem)
删除elem元素
如果元素不存在,则会发生错误
discard(elem)
如果元素不存在,不会发生错误
.clear()
清空集合
联合|
**
**
与集合的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’}
交集&
与集合AND等价,交集符号的等价方法是intersection()
差集-
等价方法是difference()
异或^
求两集合差集的并集
5.6. 字典(Dictionary)
{ : }
用于存储键值对,可以通过键来访问对应的值,键必须是不可变的类型,字典的值可以是任意类型的数据
字典的常用方法
- 创建字典
- 遍历字典
-
判断键是否在字典里面
-
提取出字典中的值
字典名['键名']
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) #结果为 {}
-
str()
将字典以字符串表示
- .keys()
显示字典里的所有键名
a = {‘name’:’value’,’age’:16} b = a.keys() for i in b: print(i)
- .values()
显示所有的值
a = {‘name’:’value’,’age’:16} b = a.values() for i in b: print(i)
- .items()
显示所有的关键字和他们的值(同时显示)
a = {‘name’:’value’,’age’:16} b = a.items() for i,j in b: print(i,j)
- update()
在字典末尾一次性追加另一个字典(用新字典扩展原来的字典)
a = {‘name’:’value’,’age’:16} c = {‘test’:123} a.update(c) print(a) #结果为 {‘name’: ‘value’, ‘age’: 16, ‘test’: 123}
5.7. 布尔(Boolean)
用于表示真(True)和假(False)两种状态。
5.8. 类型转换
-
set(s) 转换为可变集合
-
int() 转换为整型
-
str() 转换为字符型
-
float() 转换为浮点型
-
bool(x) 布尔型转换
在python3中,只有空字符串''
、""
、数字0、空字典{}
、空列表[]
、空元组()
、空数据None会被转换成为False,其他的都会被转换成为True
-
unichr(x) ASCII码转为Unicode单字符串
-
abs() 取绝对值
-
round 四舍五入保留指定小数位
-
sum 求和
-
type() 查看数据的类型
6. 拆包
*
加一个序列(列表、元组等)表示拆包,即将一个数据拆成多个数据
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
x,*y = 1,3,4,5,6 # * 设置y的长度可变
print(y)
#结果是 [3,4,5,6]
7. 序列的转换
set()
list()
tuple()
eval()
称为评估函数,作用是去掉参数中最外层引号并执行剩余语句
可转换序列的类型
a = '465'
print(type(a)) # 字符串类型
print(type(eval(a))) # int类型
多被用来执行字符串里的代码
a = 'input("请输入")' #字符串
eval(a)
转JSON
- 引入json模块
import json
.dumps()
方法
.dumps()
将字典、列表、集合等转换为JSON字符串
import json person = {‘name’:’zhangsan’,’age’:18} m = json.dumps(person) print(m)
.loads()
方法
将JSON字符串转换为python对应的类型,字典、列表等
8. 函数
8.1. 定义函数
在 Python 中,定义函数使用 def
语句。一个函数主要由三部分构成:
- 函数名
- 函数参数
- 函数返回值
如果函数没有 return
语句,则自动 return None
可以将多个数据捆绑到一个列表、字典、元组中进行return
def fun():
print('runing')
8.2. 函数参数
Python 的函数参数主要分为以下几种:
- 必选参数
- 默认参数
- 可变参数
- 关键字参数
必选参数
必选参数就是在调用函数的时候要传入数量一致的参数
默认参数
形参中默认有值的参数
有默认值的参数,一定要位于参数列表的最后面
为了避免不必要的错误,我们应该使用不可变对象作为函数的默认参数
def func(a, b=5)
#是有效的
def func(a=5, b)
#是无效的
可变参数
在定义函数的时候,无法预估函数应该制定多少个参数,这时我们就可以使用可变参数
参数前面有一个 *
号,表示是可变的
下面例子中,在函数内部,参数 args 接收到的是一个 tuple
def add(a,b,*args):
print('arg = {}'.format(args))
add(1,2,4,5,6,7)
#结果是 arg = (4, 5, 6, 7)
关键字传参
下面例子中的kwargs 就是一个关键字参数,它前面有两个 *
号。kwargs 可以接收不定长度的键值对,在函数内部,它会表示成一个 dict
def add(a,b,**kwargs):
print('kwargs = {}'.format(kwargs))
add(1,2,x = 4,y = 5)
#结果是 kwargs = {'x': 4, 'y': 5}
参数的顺序
def func(一般参数,*args,缺省参数,**kwargs)
8.3. 函数变量
在函数外声明的变量,可以在脚本程序的任意位置调用这个变量
全局变量
用来在函数内部修改全局变量
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就不能被当作形参传入函数中
内置函数
-
globals() 查看全局变量
-
locals() 查看局部变量
局部变量
在函数里声明的变量,只能在函数内部被调用而不能在函数外部调用
注:如果在函数范围内定义了具有相同名称的变量,那么它将仅打印函数内给出的值而不是全局值
9. 函数式编程
函数式编程的一大特性就是:可以把函数当成变量来使用,比如将函数赋值给其他变量、把函数作为参数传递给其他函数、函数的返回值也可以是一个函数等等
Python 中的函数式编程,主要包括以下几个方面:
- 高阶函数
- 匿名函数
- map/reduce/filter
- 闭包
- 装饰器
- partial 函数
9.1. 函数名
函数名相当于变量,指向函数体中的代码
def a():
print("输出a");
b = a; #相当于给函数起个别名
b(); #结果是 输出a
9.2. 函数的回调
把该函数当作参数传给另一个函数
#运算 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) #调用减法函数
9.3. 高阶函数
将函数当作变量一样使用。一个函数接收另一个函数作为参数,这种函数称之为高阶函数
def func(g, arr):
return [g(x) for x in arr]
- 将函数作为另一个函数的返回值
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
9.4. 内建高阶函数
map/reduce/filter 是 Python 中较为常用的内建高阶函数
- 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
9.5. 匿名函数
lambda 参数: 表达式
,冒号 :
前面的变量是该匿名函数的参数,冒号后面是函数的返回值,注意这里不需使用 return 关键字
匿名函数一般适用于创建一些临时性的,小巧的函数
调用函数
由于匿名函数本质上是一个函数对象,也可以将其赋值给另一个变量,再由该变量来调用函数
- 给函数命名(使用较少)
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)
9.6. 闭包
在 Python 中,函数也是一个对象。因此,我们在定义函数时,可以再嵌套定义一个函数,并将该嵌套函数返回
在内部函数里对外部函数的变量进行调用
在内部函数里对外部函数的变量进行修改,需要用nonlocal
声明
def outer():
m = 10
print(m)
def inner():
nonlocal m #nonlocal,进行声明
m = 50 #修改外部函数变量的值
print(m)
if True:
inner()
print(m) #前面如果不用nonlocal声明,这里将打印 10而不是50
9.7. 装饰器
用@
声明一个装饰器
给某个函数加装饰器,在该函数的前一行,声明装饰器即可
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函数
被修饰的函数无参数
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
被修饰的函数有参数
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(‘张三’)
被修饰的函数有不定长参数
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)
装饰器中的return
9.8. partial 函数
10. 文件和目录
10.1. 读写文本文件
- 推荐使用 with 语句操作文件 IO。
- 如果文件较大,可以按字节读取或按行读取。
- 使用文件迭代器进行逐行迭代
open(file,mode,encoding)
- file 文件路径(相对或者绝对路径)
windows中使用\
分隔路径,但python中\
表示转义符
python中可以使用\\
或/
分割路径,也可以使用r'路径'
表示(即在路径前加r)
- encoding 打开文件时的编码方式
open
函数的常用模式主要有:
‘r’ | 读模式 |
---|---|
‘w’ | 写模式 |
‘a’ | 追加模式 |
‘b’ | 二进制模式(可添加到其他模式中使用) |
‘+’ | 读/写模式(可添加到其他模式中使用) |
通常而言,读取文件有以下几种方式:
- 一次性读取所有内容,使用
read()
或readlines()
; - 按字节读取,使用
read(size)
; - 按行读取,使用
readline()
;
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()
读取整个文件所有行,保存在一个列表中,每行作为一个元素
write()
写数据,只能写入字符串和二进制
writelines()
写行数据,只能写入字符串和二进制
将多个值同时写入一行中
文件迭代器
在 Python 中,文件对象是可迭代的,这意味着我们可以直接在 for 循环中使用它们,而且是逐行迭代的,也就是说,效果和 readline()
是一样的,而且更简洁
按字节读取
如果文件较小,一次性读取所有内容确实比较方便。但是,如果文件很大,比如有 100G,那就不能一次性读取所有内容了。这时,我们构造一个固定长度的缓冲区,来不断读取文件内容。
10.2. 读写二进制文件
Python 支持二进制文件的读写,比如图片,声音文件等
- 读取二进制文件使用
rb
模式。 - 写入二进制文件使用
wb
模式。10.3. OS模块
Python 的 os 模块封装了常见的文件和目录操作,下面只列出部分常用的方法
方法 | 说明 |
---|---|
os.mkdir | 创建目录 |
os.rmdir | 删除目录 |
os.rename | 重命名 |
os.remove | 删除文件 |
os.getcwd | 获取当前工作路径 |
os.walk | 遍历目录 |
os.path.join | 连接目录与文件名 |
os.path.split | 分割文件名与目录 |
os.path.abspath | 获取绝对路径 |
os.path.dirname | 获取路径 |
os.path.basename | 获取文件名或文件夹名 |
os.path.splitext | 分离文件名与扩展名 |
os.path.isfile | 判断给出的路径是否是一个文件 |
os.path.isdir | 判断给出的路径是否是一个目录 |
11. 异常处理
增加程序的稳定性(健壮性),我们应该尽可能的考虑可能发生错误的点以及用户的使用方式,以使得程序不会轻易的崩溃
- Python 中所有的异常类都是从
BaseException
类派生的。 - 通过 try/except 来捕捉异常,可以使用多个 except 子句来分别处理不同的异常。
- else 子句在主 try 块没有引发异常的情况下被执行。
- finally 子句不管是否发生异常都会被执行。
- 通过继承 Exception 类可以创建自己的异常类。
11.1. try+except
except可以专门处理单一的错误或异常,也可以处理一组在元组中的错误/异常。如果没有给出错误或异常的名称,它会处理所有的错误和异常
try: 可能会出现异常的代码块 except 异常的类型: 出现异常以后的处理理语句
11.2. try+except+else
如果没有捕获到异常,那么就执行else中的代码
try: num = 100 print(num) except NameError as e: print(‘产⽣生错误了了:%s’%e) else: print(‘没有捕获到异常,真⾼高兴’)
11.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)) #结果为 没有捕获到异常,真⾼兴
11.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()
11.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 是同一个异常类型实例对象