Python常用模块

python logging模块

Python引入了logging模块来记录用户想要查看的信息。

日志级别

当我们执行如下代码:

1
2
3
4
5
6
7
import logging  # 引入logging模块
# 将信息打印到控制台上
logging.debug(u"A")
logging.info(u"B")
logging.warning(u"C")
logging.error(u"D")
logging.critical(u"E")

控制台的输出结果为:
1
2
3
WARNING:root:C
ERROR:root:D
CRITICAL:root:E

我们会发现控制台只输出了后三个日志,这是因为默认生成的root logger的level是logging.WARNING,低于该级别的就不输出了。因此在代码最上方需要改变日志级别为NOTSET
1
2
3
import logging # 引入logging模块
logging.basciConfig(level=logging.NOTSET) # 设置日志级别
logging.debug(u"如果设置了日志级别为NOTSET,那么这里可以采取debug、info的级别的内容也可以显示在控制台上了")

控制台日志输出

1
2
3
4
5
6
7
8
import logging  # 引入logging模块
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s') # logging.basicConfig函数对日志的输出格式及方式做相关配置
# 由于日志基本配置中级别设置为DEBUG,所以一下打印信息将会全部显示在控制台上
logging.info('this is a loggging info message')
logging.debug('this is a loggging debug message')
logging.warning('this is loggging a warning message')
logging.error('this is an loggging error message')
logging.critical('this is a loggging critical message')

日志文件输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import logging  # 引入logging模块
import os.path
import time
# 第一步,创建一个logger
logger = logging.getLogger()
logger.setLevel(logging.INFO) # Log等级总开关
# 第二步,创建一个handler,用于写入日志文件
rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))
log_path = os.path.dirname(os.getcwd()) + '/Logs/'
log_name = log_path + rq + '.log'
logfile = log_name
fh = logging.FileHandler(logfile, mode='w')
fh.setLevel(logging.DEBUG) # 输出到file的log等级的开关
# 第三步,定义handler的输出格式
formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
fh.setFormatter(formatter)
# 第四步,将logger添加到handler里面
logger.addHandler(fh)
# 日志
logger.debug('this is a logger debug message')
logger.info('this is a logger info message')
logger.warning('this is a logger warning message')
logger.error('this is a logger error message')
logger.critical('this is a logger critical message')

python单元测试框架-unittest

unittest最核心的原理

  • TestCase:测试用例
    • setUP:测试前准备环境的搭建
    • run:执行测试代码
    • tearDown:测试后环境的还原
  • TestSuite:多个测试用例的集合
  • TestLoader:加载TestCase到TestSuite中
  • TextTestRunner:执行测试用例,并且把结果保存在TextTestResult之中
  • test fixture:对测试用例环境的搭建和销毁

基本使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import unnittest

# 以下定义四个函数进行单元测试
def add(a, b):
return a+b
def minus(a, b):
return a-b
def multi(a, b):
return a*b
def divide(a, b):
return a/b
# 是时候展现真正的(unittest)技术了:单元测试主体部分
class TestMathFunc(unittest.TestCase):
"""Test mathfuc.py"""

def test_add(self):
"""Test method add(a, b)"""
self.assertEqual(3, add(1, 2))
self.assertNotEqual(3, add(2, 2))

def test_minus(self):
"""Test method minus(a, b)"""
self.assertEqual(1, minus(3, 2))

def test_multi(self):
"""Test method multi(a, b)"""
self.assertEqual(6, multi(2, 3))

def test_divide(self):
"""Test method divide(a, b)"""
self.assertEqual(2, divide(6, 3))
self.assertEqual(2.5, divide(5, 2))

if __name__ == '__main__':
unittest.main()
"""执行结果为:
.F..
======================================================================
FAIL: test_divide (__main__.TestMathFunc)
Test method divide(a, b)
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:/py/test_mathfunc.py", line 26, in test_divide
self.assertEqual(2.5, divide(5, 2))
AssertionError: 2.5 != 2

----------------------------------------------------------------------
Ran 4 tests in 0.000s

FAILED (failures=1)
"""
  • 在第一行给出了每一个用例执行的结果的标识,成功是 .,失败是 F,出错是 E,跳过是 S。从上面也可以看出,测试的执行跟方法的顺序没有关系,test_divide写在了第4个,但是却是第2个执行的。
  • 每个测试方法均以 test 开头,否则是不被unittest识别的。

进阶:TestSuite(组织测试)

将程序按照添加的顺序来执行。此处只需针对上文的main函数进行改进

1
2
3
4
5
6
7
8
if __name__ == '__main__':
suite = unittest.TestSuite()

tests = [TestMathFunc("test_add"), TestMathFunc("test_minus"), TestMathFunc("test_divide")]
suite.addTests(tests)

runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)

进阶:准备测试环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class TestMathFunc(unittest.TestCase):
"""Test mathfuc.py"""

def setUp(self):
print "do something before test.Prepare environment."

def tearDown(self):
print "do something after test.Clean up."

@classmethod
def setUpClass(cls):
print "This setUpClass() method only called once."

@classmethod
def tearDownClass(cls):
print "This tearDownClass() method only called once too."
  • 这两个方法在每个测试方法执行前以及执行后执行一次,setUp用来为测试准备环境,tearDown用来清理环境,已备之后的测试。
  • 如果想要在所有case执行之前准备一次环境,并在所有case执行结束之后再清理环境,我们可以用 setUpClass()tearDownClass()

os模块与sys的模块

os模块与sys模块的区分

os模块:提供了一种方便使用操作系统函数的方法

sys模块:提供访问由解释器使用或维护的变量和在与解释器交互使用到的函数

os模块常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
os.remove()删除文件  
os.rename()重命名文件
os.walk()生成目录树下的所有文件名
os.chdir()改变目录
os.mkdir/makedirs创建目录/多层目录
os.rmdir/removedirs删除目录/多层目录
os.listdir()列出指定目录的文件
os.getcwd()取得当前工作目录
os.chmod()改变目录权限
os.path.basename()去掉目录路径,返回文件名
os.path.dirname()去掉文件名,返回目录路径
os.path.join()将分离的各部分组合成一个路径名
os.path.split()返回(dirname(),basename())元组
os.path.splitext()(返回filename,extension)元组
os.path.getatime\ctime\mtime分别返回最近访问、创建、修改时间
os.path.getsize()返回文件大小
os.path.exists()是否存在
os.path.isabs()是否为绝对路径
os.path.isdir()是否为目录
os.path.isfile()是否为文件

sys模块常用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
sys.argv           命令行参数List,第一个元素是程序本身路径   
sys.modules.keys() 返回所有已经导入的模块列表
sys.exc_info() 获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
sys.exit(n) 退出程序,正常退出时exit(0)
sys.hexversion 获取Python解释程序的版本值,16进制格式如:0x020403F0
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.maxunicode 最大的Unicode值
sys.modules 返回系统导入的模块字段,key是模块名,value是模块
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
sys.stdout 标准输出
sys.stdin 标准输入
sys.stderr 错误输出
sys.exc_clear() 用来清除当前线程所出现的当前的或最近的错误信息
sys.exec_prefix 返回平台独立的python文件安装的位置
sys.byteorder 本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'
sys.copyright 记录python版权相关的东西
sys.api_version 解释器的C的API版本
sys.version_info

关于时间的模块

datetime模块获取当前时间

1
2
import datetime
nowTime = datatime.datatime.now().strftime('%Y-%m-%d %H:%M:%S') # 现在

retry模块

使用场景通常是在网络情况不太稳定时,预防超时异常

1
2
3
4
5
6
7
8
9
10
11
import random
from retrying import retry

@retry
def do_something_unreliable():
if random.randint(0, 10) > 1:
raise IOError("Broken sauce, everything is hosed!!!111one")
else:
return "Awesome sauce!"

print do_something_unreliable()

以上是官方文档的代码:给函数添加@retry装饰器后,只要有异常,那么函数会不断地重试,直到有返回值。
下面是几个常常传入装饰器的参数
1
2
3
4
# 最多尝试7次,这个最常用!
@retry(stop_max_attempt_number=7)
# 最长等待10秒
@retry(stop_max_delay=10000)

timeit

专门用来测试代码的运行时间,运行十分方便:
实例化Timer类需要两个参数,第一个参数为你需要计算运行时间的函数,类型为字符串;第二个参数为构建环境的导入语句,类型也为字符串。

例子1

1
2
3
4
5
6
7
8
9
10
11
# 用来计算运行时间的函数
def test1():
n = 0
for i in range(101):
n += i
return n
from timeit import Timer
# 实例化
t = Timer("test1()", "from __main__ import test1")
print t.timeit()
print t.repeat(3, 10000) # 执行测试三次

glob

glob是python自己带的一个文件操作相关模块,用它可以查找符合自己目的的文件,支持通配符操作: ? []]这三个通配符,代表0个或多个字符,?代表一个字符,[]匹配指定范围内的字符,如[0-9]匹配数字。主要方法如下.

glob方法:返回所有匹配的文件路径列表

1
2
glob.glob(r'C:*.txt') # 获取C盘下的所有txt文件
glog.glob(r'../*.py') # 获取相对路径下的python文件

PIL

PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准库了。PIL功能非常强大,但API却非常简单易用。

诡异的安装方式

pip install pillow

基本操作

1
2
3
4
5
from PIL import Image
im = Image.open('path/to/Image.jpg') # 打开图像文件
w, h = im.size # 获取图片尺寸
im.thumbnail((w//2, h//2)) # 缩放图片到50%
im.save('path/to/Image.jpg', 'jpeg') # 保存图片格式为jpeg

matplotlib

在远端服务器利用matplotlib绘图

import matplotlib.pyplot之前加上:

1
2
import matplotlib as mpl
mpl.use('Agg')

plt.draw之后加上:
1
plt.savefig("/path/to/pic.jpg")

setuptool

basic usage

1
2
3
4
5
6
from setuptools import setup
setup(
name='MyApp', # 应用名
version='1.0', # 版本号
packages=['myapp'] # 包括在安装包内的Python包
)

pydot & graphviz

两个包为keras的可视化模块。可以可视化神经网络结构

easydict

引用与参考资料

  1. logging:https://www.cnblogs.com/CJOKER/p/8295272.html
  2. unittest:https://blog.csdn.net/huilan_same/article/details/52944782#t4
  3. https://my.oschina.net/liuyuantao/blog/755907
  4. https://blog.csdn.net/u010472607/article/details/76857493/
  5. https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/00140767171357714f87a053a824ffd811d98a83b58ec13000
  6. https://blog.csdn.net/i_is_a_energy_man/article/details/77833040
  7. https://blog.csdn.net/zzytmxk/article/details/53402257
  8. http://python.jobbole.com/87240/
请zzy824喝杯咖啡
0%