python笔记4(调试、进程)

mac2025-11-16  16

文章目录

一、错误、调试、测试1、错误2、调试3、单元测试4、文档测试 二、IO进程1、文件读写2、`StringIO`和`BytesIO`3、操作文件和目录4、序列化 三、进程和线程1、多进程2、多线程3、ThreadLocal

一、错误、调试、测试

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()

解决了参数在一个线程中各个函数之间互相传递的问题

最新回复(0)