Python之旅上

Posted by Wh0ami-hy on April 25, 2022

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编写规范

Python PEP8 编码规范

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 是同一个异常类型实例对象


本站总访问量