python笔记4(调试、进程)

一、错误、调试、测试

1、错误

  1. 错误处理

    机制:try....except....finally

    所有的错误类型都继承自BaseException

    出错的的时候,要分析错误的调用栈信息,才能定位错误的位置

  2. 记录错误

    logging模块:记录错误信息

  3. 抛出错误

    raise抛出错误

    raise如果不带参数,就会把错误原样抛出

    expectraise一个error,还可以转化错误类型

2、调试

  1. print

    打印可能有问题的变量

  2. assert(断言)

    代替print :assert n!=0, 'n is zero'

    断言n!=0,即n!=0是正确的,如果断言失败,assert本身会抛出AssertionError

    启动python解释器时,可以通过-0参数来关闭assert:python -0 err.py

  3. logging

    不会抛出错误,而且还可以输出到文件

    输出一段文本:logging.info()

    logging允许指定记录信息的级别:DEBUGINFOWARNINGERROR;当指定后,它前面的级别就不会起作用:指定level=WARINGDEBUGINFO不起作用

    还可以通过配置,一条语句输出到不同的地方

  4. pdb

    命令行启动python调试器pdb,让程序以单步的方式运行

    python -m pdb err.py,启动后,pdb定位到下一步要执行的代码

    • 输入1查看代码
    • 输入n可以单步执行代码
    • 输入p 变量名查看变量
    • 输入q结束调试,退出程序
  5. pdb.set_trace()

    使用pdb,但不需要单步执行,只需import pdb,然后在可能出错的地方放一个pdb.set_trace()设置一个断点

    • p查看变量
    • c继续执行
  6. 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

setUptearDown

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、StringIOBytesIO

  • 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 x
    • ntWindows
  • 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、序列化

把变量从内存中变成可存储或传输的过程叫序列化

dumpsloadsbytes进行操作

dumploadfile-like Object进行操作

pickle模块实现序列化

  • pickle.dumps()

    把任意对象序列化成一个bytes

  • pickle.loads()

    从bytes中反序列化出对象

json模块转换格式

  • json.dumps()
  • json.loads()
  • 将class转化为json
    • 写一个转换函数
    • 使用__dict__属性

三、进程和线程

1、多进程

  • fork()函数

    linuxfork()函数,调用一次,返回两次,父进程与子进程分别一次。子进程永远返回0,父进程返回子进程的ID

  • multiprocessing:跨平台版本的多进程模块

    multiprocessing提供了一个Process类代表进程

    创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动

    join()方法可以等待子进程结束后再继续往下执行

  • Pool:启动大量的子进程

    p = Pool() #pool的默认大小是cpu的数量

    pool对象调用join方法会等待所有子进程执行完毕,调用join之前必须调用close

  • 控制子进程输入输出:subprocess模块

    子进程输入:communicate

  • 进程通信

    QueuePipes

    在Queue中,put写数据,get读数据

2、多线程

  • _threadthreading

    启动一个线程:把一个函数传入并创建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()

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

发布了41 篇原创文章 · 获赞 28 · 访问量 9066

猜你喜欢

转载自blog.csdn.net/wang15877/article/details/102863227