文章目录
一、错误、调试、测试
1、错误
-
错误处理
机制:
try....except....finally
所有的错误类型都继承自
BaseException
出错的的时候,要分析错误的调用栈信息,才能定位错误的位置
-
记录错误
logging
模块:记录错误信息 -
抛出错误
raise
抛出错误raise
如果不带参数,就会把错误原样抛出在
expect
中raise
一个error,还可以转化错误类型
2、调试
-
print
打印可能有问题的变量
-
assert
(断言)代替
print
:assert n!=0, 'n is zero'
断言n!=0,即n!=0是正确的,如果断言失败,
assert
本身会抛出AssertionError
启动python解释器时,可以通过
-0
参数来关闭assert
:python -0 err.py
-
logging
不会抛出错误,而且还可以输出到文件
输出一段文本:
logging.info()
logging允许指定记录信息的级别:
DEBUG
,INFO
,WARNING
,ERROR
;当指定后,它前面的级别就不会起作用:指定level=WARING
,DEBUG
和INFO
不起作用还可以通过配置,一条语句输出到不同的地方
-
pdb
命令行启动python调试器
pdb
,让程序以单步的方式运行python -m pdb err.py
,启动后,pdb
定位到下一步要执行的代码- 输入
1
查看代码 - 输入
n
可以单步执行代码 - 输入
p 变量名
查看变量 - 输入
q
结束调试,退出程序
- 输入
-
pdb.set_trace()
使用
pdb
,但不需要单步执行,只需import pdb
,然后在可能出错的地方放一个pdb.set_trace()
设置一个断点p
查看变量c
继续执行
-
IDE
3、单元测试
编写单元测试:
- 引入
unittset
模块 - 编写一个测试类,从
unittest.TestCase
继承 - 每一类测试都需要编写一个
test_xxx()
方法,测试方法以test
开头 - 常用断言:
assertEqual()
:self.assertEqual(abs(-1),1)
assertRaises()
:with self.assertRaises(KeyError)
运行单元测试:
-
在最后加上两行代码:
if __name__ == '__math__': unittest.main()
-
在命令行中通过参数
-m unitest
进行单元测试python -m unittest mydict_test
setUp
与tearDown
setUp
方法与tearDown
方法,会分别在每一个调用一个测试方法的前后被执行
4、文档测试
内置的文档测试(doctest)模块可以直接提取注释中的代码并正确执行测试
只有在命令行直接运行时,才执行doctset
二、IO进程
1、文件读写
读写文件函数与c语言一致
读写文件:请求操作系统打开一个文件对象(文件描述符),然后通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)
-
打开文件:
open()
函数f = open('路径', 'r')
如果文件不存在,抛出一个
IOError
错误 -
读文件:
read()
-
f.read()
:一次读取文件全部内容到内存中,用一个str
对象表示 -
read(size)
:每次最多读取size个字节 -
readline()
:每次读取一行内容 -
readlines()
:一次读取所有内容并按行返回for line in f.readlines(): print(line.strip()) #把末尾的'\n'删除
小文件
read()
,不确定read(size)
,配置文件类readlines
-
-
写文件:
write()
with open ('路径', 'w') as f:
-
写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存中,空闲的时候在慢慢写入,只有调用
close()
方法,操作系统才保证把还没有写入磁盘的内容全部写入磁盘 -
写入特定编码的文本文件,在
open()
中传入encoding
参数,将字符串自动转成指定编码 -
以
w
模式写入,若文件已存在,会直接覆盖;如果想追加到文件末尾传入参数a
以追加(append)模式写入
-
-
关闭文件:
close
f.close()
-
用
try...finally
保证正确关闭文件 -
with
语句自动调用close()
with open(...) as f
-
-
file-like Object:
有
read()
方法StringIO
就是在内存中创建的file-like Object -
二进制文件:用
rb
打开即可 -
字符编码:
encoding
-
给
open()
函数传入encoding
参数 -
文件中夹杂非法编码字符,出现
UnicodeDecodeError
问题,给opend
传入errors
参数f = open('路径', 'r', encoding='gbk', errors='ingore')
-
2、StringIO
和BytesIO
-
StringIO
:在内存中读写str
-
写入
StringIO
创建一个
StringIO
,后与文件一样from io import StringIO f = StringIO() f.write(' ')
getvalue
用于获得写入后的str
-
读取
StringIO
初始化
StringIO
,然后像文件一样读取
-
-
BytesIO
3、操作文件和目录
操作系统提供的命令指示简单的调用了操作系统提供的接口函数;python提供的os
模块也可以直接调用接口函数
os.name
:操作系统类型posix
:Linux、Unix、Mac os xnt
:Windows
os.environ
:环境变量(获取某个值:os.environ.get('key')
)
操作文件和目录:
操作文件和目录的函数一部分放在os
模块中,部分放在os.path
中
-
- 查看当前绝对路径:
os.path.abspath('.')
- 创建目录:
os.path.join('路径')
- 删除目录:
os.rmdir('路径')
- 合成路径:
os.path.join()
(可以正确处理不同操作系统的路径分隔符) - 拆分路径:
os.path.spilt()
- 文件扩展名:
os.path.splitext()
- 文件重命名:
os.rename()
- 删除文件:
os.remove()
- 过滤文件
- 查看当前绝对路径:
4、序列化
把变量从内存中变成可存储或传输的过程叫序列化
dumps
和loads
对bytes
进行操作
dump
和load
对file-like Object
进行操作
pickle
模块实现序列化
-
pickle.dumps()
把任意对象序列化成一个
bytes
-
pickle.loads()
从bytes中反序列化出对象
json
模块转换格式
json.dumps()
json.loads()
- 将class转化为json
- 写一个转换函数
- 使用
__dict__
属性
三、进程和线程
1、多进程
-
fork()函数
linux
中fork()
函数,调用一次,返回两次,父进程与子进程分别一次。子进程永远返回0,父进程返回子进程的ID -
multiprocessing
:跨平台版本的多进程模块multiprocessing
提供了一个Process
类代表进程创建子进程时,只需要传入一个执行函数和函数的参数,创建一个
Process
实例,用start()
方法启动join()
方法可以等待子进程结束后再继续往下执行 -
Pool
:启动大量的子进程p = Pool()
#pool的默认大小是cpu的数量pool对象调用join方法会等待所有子进程执行完毕,调用join之前必须调用close
-
控制子进程输入输出:
subprocess
模块子进程输入:
communicate
-
进程通信
Queue
、Pipes
等在Queue中,put写数据,get读数据
2、多线程
-
_thread
和threading
启动一个线程:把一个函数传入并创建
Thread
实例,调用start()
启用主线程:进程默认启动的线程threading模块有个current_thread()函数,返回当前线程实例
-
lock()
:保证一个线程在修改时,别的线程不能改threading.Lock()
:-
创建一个锁:
lock = threading.Lock()
-
获取锁:
lock.acquire()
-
释放锁:
lock.release()
-
当多个进程同时执行acquire时,只能有一个线程能获取锁,然后继续执行,其余线程需等待第一个进程结束后再获取锁
保证某些关键代码能完整执行
python解释器有GIL全局锁,导致多线程无法利用多核
3、ThreadLocal
创建全局ThreadLocal
对象:
local_school = threading.local()
解决了参数在一个线程中各个函数之间互相传递的问题