Day05 - Python 经常使用模块

1. 模块简介

模块就是一个保存了 Python 代码的文件。模块能定义函数,类和变量。模块里也能包含可执行的代码。python

模块也是 Python 对象,具备随机的名字属性用来绑定或引用。linux

下例是个简单的模块support.pygit

1 def print_func( par ):
2      print("Hello : ", par)
3      return

1)import 语句程序员

想使用 Python 源文件,只需在另外一个源文件里执行 import 语句,语法以下:正则表达式

import module1[, module2[,... moduleN]

当解释器遇到 import 语句,若是模块在当前的搜索路径就会被导入。shell

搜索路径是一个解释器会先进行搜索的全部目录的列表。如想要导入模块 support.py ,须要把命令放在脚本的顶端:apache

1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3  
4 # 导入模块
5 import support
6  
7 # 如今能够调用模块里包含的函数了
8 support.print_func("Zara")

输出结果:json

1 Hello : Zara

一个模块只会被导入一次,无论你执行了多少次 import ,这样能够防止导入模块被一遍又一遍地执行。vim

2)from … import 语句缓存

Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。语法以下:

from modname import name1[, name2[, ... nameN]]

例如,要导入模块 fib 的 fibonacci 函数,使用以下语句:

from fib import fibonacci

这个声明不会把整个 fib 模块导入到当前的命名空间中,它只会将 fib 里的 fibonacci 单个引入到执行这个声明的模块的全局符号表。

3)from … import * 语句

把一个模块的全部内容全都导入到当前的命名空间也是可行的,只需使用以下声明:

from modname import *

这提供了一个简单的方法来导入一个模块中的全部项目,然而这种声明不应被过多地使用。

4)定位模块

当你导入一个模块,Python 解析器对模块位置的搜索顺序是:

  • 当前目录
  • 若是不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每一个目录
  • 若是都找不到,Python 会察看默认路径。UNIX 下,默认路径通常为 /usr/local/lib/python/ 。

模块搜索路径存储在 system 模块的 sys.path 变量中。变量里包含当前目录,PYTHONPATH 和由安装过程决定的默认目录。

5) PYTHONPATH变量

做为环境变量,PYTHONPATH 由装在一个列表里的许多目录组成。PYTHONPATH 的语法和 shel l 变量的 PATH 同样。

在Windows系统,典型的PYTHONPATH以下:

1 >>> import sys
2 >>> sys.path
3 ['', 'C:\\Python35\\Lib\\idlelib', 'C:\\Python35\\python35.zip', 'C:\\Python35\\DLLs', 'C:\\Python35\\lib', 'C:\\Python35', 'C:\\Python35\\lib\\site-packages']

在UNIX系统,典型的PYTHONPATH以下:

1 >>> import sys
2 >>> sys.path
3 ['', '/usr/local/python35/lib/python35.zip', '/usr/local/python35/lib/python3.5', '/usr/local/python35/lib/python3.5/plat-linux', '/usr/local/python35/lib/python3.5/lib-dynload', '/usr/local/python35/lib/python3.5/site-packages']

6) 命名空间和做用域

变量是拥有匹配对象的名字(标识符)。命名空间是一个包含了变量名称们(键)和它们各自相应的对象们(值)的字典。

一个 Python 表达式能够访问局部命名空间和全局命名空间里的变量。

若是一个局部变量和一个全局变量重名,则局部变量会覆盖全局变量。

每一个函数都有本身的命名空间。类的方法的做用域规则和一般函数的同样。

Python 会智能地猜想一个变量是局部的仍是全局的,它假设任何在函数内赋值的变量都是局部的。

所以,若是要给全局变量在一个函数里赋值,必须使用 global  语句。

global VarName 的表达式会告诉 Python , VarName 是一个全局变量,这样 Python 就不会在局部命名空间里寻找这个变量了。

例如,咱们在全局命名空间里定义一个变量 money ,咱们再在函数内给变量 money 赋值,而后 Python 会假定 money 是一个局部变量。然而,咱们并无在访问前声明一个局部变量 money ,结果就是会出现一个 UnboundLocalError 的错误。取消 global 语句的注释就能解决这个问题。

 1 >>> money = 2000
 2 >>> def add_money():
 3     # 想改正代码就取消如下注释
 4     # global money
 5     money += 1
 6 
 7     
 8 >>> print(money)
 9 2000
10 >>> add_money()
11 Traceback (most recent call last):
12   File "<pyshell#7>", line 1, in <module>
13     add_money()
14   File "<pyshell#5>", line 4, in add_money
15     money += 1
16 UnboundLocalError: local variable 'money' referenced before assignment
17 >>> print(money)

取消注释:

 1 >>> money = 2000
 2 >>> def add_money():
 3     global money
 4     money += 1
 5 
 6     
 7 >>> print(money)
 8 2000
 9 >>> add_money()
10 >>> print(money)
11 2001

7)Python 中的包

包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。

考虑一个在 Phone 目录下的 pots.py 文件。这个文件有以下源代码:

1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3  
4 def Pots():
5     print("I'm Pots Phone")

一样地,咱们有另外两个保存了不一样函数的文件:

  • Phone/Isdn.py 含有函数 Isdn()
  • Phone/G3.py 含有函数 G3()

如今,在 Phone 目录下建立file __init__.py:

  • Phone/__init__.py

当你导入 Phone 时,为了可以使用全部函数,你须要在 __init__.py 里使用显式的导入语句,以下:

from Pots import Pots from Isdn import Isdn from G3 import G3

当你把这些代码添加到 __init__.py 以后,导入Phone包的时候这些类就全都是可用的了。

1 #!/usr/bin/python
2 # -*- coding: UTF-8 -*-
3  
4 # 导入 Phone 包
5 import Phone
6  
7 Phone.Pots()
8 Phone.Isdn()
9 Phone.G3()

输出结果:

1 I'm Pots Phone
2 I'm 3G Phone
3 I'm ISDN Phone

如上,为了举例,咱们只在每一个文件里放置了一个函数,但其实你能够放置许多函数。

也能够在这些文件里定义Python的类,而后为这些类建一个包。

8) dir() 函数

dir() 函数一个排好序的字符串列表,内容是一个模块里定义过的名字。

返回的列表容纳了在一个模块里定义的全部模块、变量和函数。

以下一个简单的实例:

1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3  
4 # 导入内置 math 模块
5 import math
6 
7 dir(math)

以上实例输出结果:

1 ['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

在这里,特殊字符串变量 __name__ 指向模块的名字,__file__ 指向该模块的导入文件名。

9) globals() 和 locals() 函数

根据调用地方的不一样,globals() 和 locals() 函数可被用来返回全局和局部命名空间里的名字。

若是在函数内部调用 locals() ,返回的是全部能在该函数里访问的命名。

1 >>> locals()
2 {'__spec__': None, '__name__': '__main__', '__doc__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__builtins__': <module 'builtins' (built-in)>, 'math': <module 'math' (built-in)>, '__package__': None}

若是在函数内部调用 globals(),返回的是全部在该函数里能访问的全局名字。

1 >>> globals()
2 {'__spec__': None, '__name__': '__main__', '__doc__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__builtins__': <module 'builtins' (built-in)>, 'math': <module 'math' (built-in)>, '__package__': None}

两个函数的返回类型都是字典,因此名字能用 keys() 函数获取。

10) reload() 函数

当一个模块被导入到一个脚本,模块顶层部分的代码只会被执行一次。

所以,若是你想从新执行模块里顶层部分的代码,能够用 reload() 函数。

该函数会从新导入以前导入过的模块。语法以下:

reload(module_name)

在这里,module_name 要直接放模块的名字,而不是一个字符串形式。好比想重载 hello 模块,以下:

reload(hello)

2. 经常使用模块

1) time & calendar & datetime

Python 日期和时间

Python 程序能用不少方式处理日期和时间,转换日期格式是一个常见的功能。

Python 提供了一个 time 和 calendar 模块能够用于格式化日期和时间。

时间间隔是以秒为单位的浮点小数。

每一个时间戳都以自从1970年1月1日午夜(历元)通过了多长时间来表示。

Python 的 time 模块下有不少函数能够转换常见日期格式。如函数time.time()用于获取当前时间戳, 以下实例:

1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3 
4 import time # 引入time模块
5 
6 ticks = time.time()
7 print("当前时间戳为:", ticks)

输出结果:

1 当前时间戳为: 1479129524.694309

时间戳单位最适于作日期运算。可是1970年以前的日期就没法以此表示了。太遥远的日期也不行,UNIX和Windows只支持到2038年。

时间元组

不少Python函数用一个元组装起来的9组数字处理时间:

序号 字段
0 4位数年 2008
1 1 到 12
2 1到31
3 小时 0到23
4 分钟 0到59
5 0到61 (60或61 是闰秒)
6 一周的第几日 0到6 (0是周一)
7 一年的第几日 1到366 (儒略历)
8 夏令时 -1, 0, 1, -1是决定是否为夏令时的旗帜

上述也就是struct_time元组。这种结构具备以下属性:

序号 属性
0 tm_year 2008
1 tm_mon 1 到 12
2 tm_mday 1 到 31
3 tm_hour 0 到 23
4 tm_min 0 到 59
5 tm_sec 0 到 61 (60或61 是闰秒)
6 tm_wday 0到6 (0是周一)
7 tm_yday 1 到 366(儒略历)
8 tm_isdst -1, 0, 1, -1是决定是否为夏令时的旗帜

获取当前时间

从返回浮点数的时间辍方式向时间元组转换,只要将浮点数传递给如localtime之类的函数。

1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3 
4 import time
5 
6 localtime = time.localtime(time.time())
7 print("本地时间为 :", localtime)

输出结果:

1 本地时间为 : time.struct_time(tm_year=2016, tm_mon=11, tm_mday=14, tm_hour=21, tm_min=21, tm_sec=2, tm_wday=0, tm_yday=319, tm_isdst=0)

获取格式化的时间

能够根据需求选取各类格式的时间,可是最简单的获取可读时间模式的函数是asctime():

1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3 
4 import time
5 
6 localtime = time.asctime(time.localtime(time.time()))
7 print("本地时间为 :", localtime)

输出结果:

1 本地时间为 : Mon Nov 14 21:24:39 2016

格式化日期

可使用 time 模块的 strftime 方法来格式化日期

time.strftime(format[, t])
 1 #!/usr/bin/env python
 2 # -*- coding: UTF-8 -*-
 3 
 4 import time
 5 
 6 # 格式化成2016-03-20 11:45:39形式
 7 print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
 8 
 9 # 格式化成Sat Mar 28 22:24:24 2016形式
10 print(time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))
11 
12 # 将格式字符串转换为时间戳
13 a = "Mon Nov 14 21:31:45 2016"
14 print(time.mktime(time.strptime(a, "%a %b %d %H:%M:%S %Y")))

输出结果:

2016-11-14 21:32:21
Mon Nov 14 21:32:21 2016
1479130305.0

python中时间日期格式化符号:

  • %y 两位数的年份表示(00-99)
  • %Y 四位数的年份表示(000-9999)
  • %m 月份(01-12)
  • %d 月内中的一天(0-31)
  • %H 24小时制小时数(0-23)
  • %I 12小时制小时数(01-12)
  • %M 分钟数(00=59)
  • %S 秒(00-59)
  • %a 本地简化星期名称
  • %A 本地完整星期名称
  • %b 本地简化的月份名称
  • %B 本地完整的月份名称
  • %c 本地相应的日期表示和时间表示
  • %j 年内的一天(001-366)
  • %p 本地A.M.或P.M.的等价符
  • %U 一年中的星期数(00-53)星期天为星期的开始
  • %w 星期(0-6),星期天为星期的开始
  • %W 一年中的星期数(00-53)星期一为星期的开始
  • %x 本地相应的日期表示
  • %X 本地相应的时间表示
  • %Z 当前时区的名称
  • %% %号自己

获取某月日历

Calendar模块有很普遍的方法用来处理年历和月历,例如打印某月的月历:

1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3 
4 import calendar
5 
6 cal = calendar.month(2016, 11)
7 print("如下输出2016年11月份的日历:")
8 print(cal)

输出结果:

1 如下输出2016年11月份的日历:
2    November 2016
3 Mo Tu We Th Fr Sa Su
4     1  2  3  4  5  6
5  7  8  9 10 11 12 13
6 14 15 16 17 18 19 20
7 21 22 23 24 25 26 27
8 28 29 30

time 模块

time 模块包含如下内置函数

  • time.altzone 返回格林威治西部的夏令时地区的偏移秒数(与UTC的时间差)。若是该地区在格林威治东部会返回负值(如西欧,包括英国)。对夏令时启用地区才能使用
1 >>> time.altzone
2 -32400
  • time.asctime([tupletime]) 接受时间元组并返回一个可读的形式为 'Mon Nov 14 21:45:06 2016' 的24个字符的字符串
1 >>> time.asctime(time.localtime())
2 'Mon Nov 14 21:45:06 2016'
  • time.clock() 用以浮点数计算的秒数返回当前的CPU时间。用来衡量不一样程序的耗时,比time.time()更有用
1 >>> time.clock()
2 2.83648743983101e-06
  • time.ctime([secs]) 做用至关于asctime(localtime(secs)),未给参数至关于asctime()
1 >>> time.ctime()
2 'Mon Nov 14 21:48:23 2016'
  • time.gmtime([secs]) 接收时间辍(1970纪元后通过的浮点秒数)并返回格林威治天文时间下的时间元组t。注:t.tm_isdst 始终为0
1 >>> time.gmtime()
2 time.struct_time(tm_year=2016, tm_mon=11, tm_mday=14, tm_hour=13, tm_min=49, tm_sec=3, tm_wday=0, tm_yday=319, tm_isdst=0)
  • time.localtime([secs]) 接收时间辍(1970纪元后通过的浮点秒数)并返回当地时间下的时间元组t(t.tm_isdst可取0或1,取决于当地当时是否是夏令时)
1 >>> time.localtime()
2 time.struct_time(tm_year=2016, tm_mon=11, tm_mday=14, tm_hour=21, tm_min=50, tm_sec=10, tm_wday=0, tm_yday=319, tm_isdst=0)
  • time.mktime(tupletime) 接受时间元组并返回时间辍(1970纪元后通过的浮点秒数)
1 >>> time.mktime(time.localtime())
2 1479131695.0
  • time.sleep(secs) 推迟调用线程的运行,secs指秒数
1 >>> print("Start : %s" % time.ctime())
2 Start : Mon Nov 14 21:59:15 2016
3 >>> time.sleep(5)
4 >>> print("End : %s" % time.ctime())
5 End : Mon Nov 14 21:59:20 2016
  • time.strftime(fmt[,tupletime]) 接收以时间元组,并返回以可读字符串表示的当地时间,格式由fmt决定
1 >>> time.strftime("%b %d %Y %H:%M:%S", time.gmtime())
2 'Nov 14 2016 14:01:42'
  • time.strptime(str,fmt='%a %b %d %H:%M:%S %Y') 根据fmt的格式把一个时间字符串解析为时间元组
1 >>> struct_time = time.strptime("30 Nov 16", "%d %b %y")
2 >>> print(struct_time)
3 time.struct_time(tm_year=2016, tm_mon=11, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=335, tm_isdst=-1)
  • time.time( ) 返回当前时间的时间戳(1970纪元后通过的浮点秒数)
1 >>> time.time()
2 1479132293.9487014

时间转换

日历(Calendar)模块

此模块的函数都是日历相关的,例如打印某月的字符月历。

星期一是默认的每周第一天,星期天是默认的最后一天。

更改设置需调用 calendar.setfirstweekday() 函数。

模块包含了如下内置函数:

  • calendar.calendar(year,w=2,l=1,c=6) 返回一个多行字符串格式的year年年历,3个月一行,间隔距离为c,每日宽度间隔为w字符,每行长度为21* W+18+2* C,l是每星期行数
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 import calendar
5 
6 print(calendar.calendar(2016, w=2, l=1, c=6))

输出结果:

 1                                   2016
 2 
 3       January                   February                   March
 4 Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
 5              1  2  3       1  2  3  4  5  6  7          1  2  3  4  5  6
 6  4  5  6  7  8  9 10       8  9 10 11 12 13 14       7  8  9 10 11 12 13
 7 11 12 13 14 15 16 17      15 16 17 18 19 20 21      14 15 16 17 18 19 20
 8 18 19 20 21 22 23 24      22 23 24 25 26 27 28      21 22 23 24 25 26 27
 9 25 26 27 28 29 30 31      29                        28 29 30 31
10 
11        April                      May                       June
12 Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
13              1  2  3                         1             1  2  3  4  5
14  4  5  6  7  8  9 10       2  3  4  5  6  7  8       6  7  8  9 10 11 12
15 11 12 13 14 15 16 17       9 10 11 12 13 14 15      13 14 15 16 17 18 19
16 18 19 20 21 22 23 24      16 17 18 19 20 21 22      20 21 22 23 24 25 26
17 25 26 27 28 29 30         23 24 25 26 27 28 29      27 28 29 30
18                           30 31
19 
20         July                     August                  September
21 Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
22              1  2  3       1  2  3  4  5  6  7                1  2  3  4
23  4  5  6  7  8  9 10       8  9 10 11 12 13 14       5  6  7  8  9 10 11
24 11 12 13 14 15 16 17      15 16 17 18 19 20 21      12 13 14 15 16 17 18
25 18 19 20 21 22 23 24      22 23 24 25 26 27 28      19 20 21 22 23 24 25
26 25 26 27 28 29 30 31      29 30 31                  26 27 28 29 30
27 
28       October                   November                  December
29 Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
30                 1  2          1  2  3  4  5  6                1  2  3  4
31  3  4  5  6  7  8  9       7  8  9 10 11 12 13       5  6  7  8  9 10 11
32 10 11 12 13 14 15 16      14 15 16 17 18 19 20      12 13 14 15 16 17 18
33 17 18 19 20 21 22 23      21 22 23 24 25 26 27      19 20 21 22 23 24 25
34 24 25 26 27 28 29 30      28 29 30                  26 27 28 29 30 31
35 31
  • calendar.firstweekday() 返回当前每周起始日期的设置。默认状况下,首次载入 calendar 模块时返回0,即星期一。
1 >>> calendar.firstweekday()
2 0
  • calendar.isleap(year) 是闰年返回True,不然为false。
1 >>> calendar.isleap(2016)
2 True
  • calendar.leapdays(y1,y2) 返回在Y1,Y2两年之间的闰年总数。
1 >>> calendar.leapdays(2000, 2016)
2 4
  • calendar.month(year,month,w=2,l=1) 返回一个多行字符串格式的 year 年 month 月日历,两行标题,一周一行,每日宽度间隔为 w 字符,每行的长度为7* w+6,l是每星期的行数
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 import calendar
5 
6 print(calendar.month(2016, 11, w=2, l=1))

输出结果:

1    November 2016
2 Mo Tu We Th Fr Sa Su
3     1  2  3  4  5  6
4  7  8  9 10 11 12 13
5 14 15 16 17 18 19 20
6 21 22 23 24 25 26 27
7 28 29 30
  • calendar.monthcalendar(year, month) 返回一个整数的单层嵌套列表。每一个子列表装载表明一个星期的整数,Year 年month 月外的日期都设为0,范围内的日子都由该月第几日表示,从1开始
>>> calendar.monthcalendar(2016, 11)
[[0, 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, 0, 0, 0, 0]]
  • calendar.monthrange(year,month) 返回两个整数。第一个是该月的星期几的日期码,第二个是该月的日期码,日从0(星期一)到6(星期日),月从1到12
1 >>> calendar.monthrange(2016, 11)
2 (1, 30)
  • calendar.prcal(year,w=2,l=1,c=6) 至关于 print(calendar.calendar(year,w,l,c))
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 import calendar
5 
6 print(calendar.prcal(2016, w=2, l=1, c=6))

输出结果:

                                  2016

      January                   February                   March
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
             1  2  3       1  2  3  4  5  6  7          1  2  3  4  5  6
 4  5  6  7  8  9 10       8  9 10 11 12 13 14       7  8  9 10 11 12 13
11 12 13 14 15 16 17      15 16 17 18 19 20 21      14 15 16 17 18 19 20
18 19 20 21 22 23 24      22 23 24 25 26 27 28      21 22 23 24 25 26 27
25 26 27 28 29 30 31      29                        28 29 30 31

       April                      May                       June
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
             1  2  3                         1             1  2  3  4  5
 4  5  6  7  8  9 10       2  3  4  5  6  7  8       6  7  8  9 10 11 12
11 12 13 14 15 16 17       9 10 11 12 13 14 15      13 14 15 16 17 18 19
18 19 20 21 22 23 24      16 17 18 19 20 21 22      20 21 22 23 24 25 26
25 26 27 28 29 30         23 24 25 26 27 28 29      27 28 29 30
                          30 31

        July                     August                  September
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
             1  2  3       1  2  3  4  5  6  7                1  2  3  4
 4  5  6  7  8  9 10       8  9 10 11 12 13 14       5  6  7  8  9 10 11
11 12 13 14 15 16 17      15 16 17 18 19 20 21      12 13 14 15 16 17 18
18 19 20 21 22 23 24      22 23 24 25 26 27 28      19 20 21 22 23 24 25
25 26 27 28 29 30 31      29 30 31                  26 27 28 29 30

      October                   November                  December
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
                1  2          1  2  3  4  5  6                1  2  3  4
 3  4  5  6  7  8  9       7  8  9 10 11 12 13       5  6  7  8  9 10 11
10 11 12 13 14 15 16      14 15 16 17 18 19 20      12 13 14 15 16 17 18
17 18 19 20 21 22 23      21 22 23 24 25 26 27      19 20 21 22 23 24 25
24 25 26 27 28 29 30      28 29 30                  26 27 28 29 30 31
31

None
  • calendar.prmonth(year,month,w=2,l=1) 至关于 print(calendar.calendar(year,w,l,c))
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 import calendar
5 
6 calendar.prmonth(2016, 11, w=2, l=1)

输出结果:

1    November 2016
2 Mo Tu We Th Fr Sa Su
3     1  2  3  4  5  6
4  7  8  9 10 11 12 13
5 14 15 16 17 18 19 20
6 21 22 23 24 25 26 27
7 28 29 30
  • calendar.setfirstweekday(weekday) 设置每周的起始日期码。0(星期一)到6(星期日)
1 >>> calendar.setfirstweekday(2)
2 >>> calendar.firstweekday( )
3 2
  • calendar.timegm(tupletime) 和 time.gmtime 相反:接受一个时间元组形式,返回该时刻的时间辍(1970纪元后通过的浮点秒数)
1 >>> calendar.timegm(time.localtime())
2 1479164045
  • calendar.weekday(year,month,day) 返回给定日期的日期码。0(星期一)到6(星期日)。月份为 1(一月) 到 12(12月)
1 >>> calendar.weekday(2016,11,14)
2 0

datetime 模块

  • datetime.datetime.now() 返回当前时间
1 >>> print(datetime.datetime.now())
2 2016-11-14 23:02:30.931429
  • datetime.date.fromtimestamp(time.time()) 时间戳直接转成日期格式
1 >>> print(datetime.date.fromtimestamp(time.time()))
2 2016-11-14
  • datetime.datetime.now() + datetime.timedelta(3)) 当前时间+3天
  • datetime.datetime.now() + datetime.timedelta(-3)) 当前时间-3天
  • datetime.datetime.now() + datetime.timedelta(hours=3)) 当前时间+3小时
  • datetime.datetime.now() + datetime.timedelta(minutes=30) 当前时间+30分
 1 >>> print(datetime.datetime.now())
 2 2016-11-14 23:05:03.731169
 3 >>> print(datetime.datetime.now() + datetime.timedelta(3)) # 当前时间+3天
 4 2016-11-17 23:05:03.743169
 5 >>> print(datetime.datetime.now() + datetime.timedelta(-3)) # 当前时间-3天
 6 2016-11-11 23:05:03.755170
 7 >>> print(datetime.datetime.now() + datetime.timedelta(hours=3)) # 当前时间+3小时
 8 2016-11-15 02:05:03.765171
 9 >>> print(datetime.datetime.now() + datetime.timedelta(minutes=30)) # 当前时间+30分
10 2016-11-14 23:35:04.858233
  • replace(minute, hour) 时间替换
1 >>> c_time = datetime.datetime.now()
2 >>> print(c_time)
3 2016-11-14 23:07:37.762979
4 >>> print(c_time.replace(minute=3, hour=2))
5 2016-11-14 02:03:37.762979

2)random

Python中的random模块用于生成随机数

random.random()

用于生成一个0到1的随机浮点数: 0 <= n < 1.0

1 >>> import random
2 >>> random.random()
3 0.99107532292498801

random.uniform(a, b)

用于生成一个指定范围内的随机浮点数,两个参数其中一个是上限,一个是下限。若是a > b,则生成的随机数n: a <= n <= b;若是 a <b, 则 b <= n <= a。

1 >>> import random
2 >>> random.uniform(10, 20)
3 12.893035403821591
4 >>> random.uniform(20, 10)
5 15.344944314032574

random.randint(a, b)

用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b

 1 >>> import random
 2 >>> random.randint(12, 20)    # 生成的随机数n: 12 <= n <= 20
 3 16
 4 >>> random.randint(20, 20)    # 结果永远是20
 5 20
 6 >>> random.randint(20, 10)    # 该语句是错误的,下限必须小于上限
 7 Traceback (most recent call last):
 8   File "<stdin>", line 1, in <module>
 9   File "/usr/lib64/python2.6/random.py", line 228, in randint
10     return self.randrange(a, b+1)
11   File "/usr/lib64/python2.6/random.py", line 204, in randrange
12     raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width)
13 ValueError: empty range for randrange() (20,11, -9)

random.randrange([start], stop[, step])

从指定范围内,按指定基数递增的集合中获取一个随机数。

1 >>> import random
2 >>> random.randrange(10, 100, 2)
3 80

结果至关于从 [10, 12, 14, 16, ... 96, 98] 序列中获取一个随机数。

random.randrange(10, 100, 2)在结果上与 random.choice(range(10, 100, 2) 等效。

random.choice(sequence)

从序列中获取一个随机元素,参数 sequence 表示一个有序类型。这里要说明 一下:sequence 在python 不是一种特定的类型,而是泛指一系列的类型。list, tuple, 字符串都属于sequence。

1 >>> import random
2 >>> random.choice("学习Python") 
3 '\xe4'
4 >>> random.choice(["JGood", "is", "a", "handsome", "boy"]) 
5 'boy'
6 >>> random.choice(("Tuple", "List", "Dict"))
7 'List'

random.shuffle(x[, random])

用于将一个列表中的元素打乱

1 >>> import random
2 >>> p = ["Python", "is", "powerful", "simple", "and so on..."]  
3 >>> random.shuffle(p)  
4 >>> p
5 ['is', 'Python', 'and so on...', 'powerful', 'simple']

random.sample(sequence, k)

从指定序列中随机获取指定长度的片,sample函数不会修改原有序列

1 >>> import random
2 >>> list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  
3 >>> slice = random.sample(list, 5) 
4 >>> slice
5 [8, 6, 9, 3, 7]
6 >>> list
7 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

多个字符中选取特定数量的字符

1 >>> import random
2 >>> random.sample('abcdefghij',3) 
3 ['i', 'c', 'b']

random.sample 验证码应用

方式一:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import random
 5 import string
 6 
 7 str_source = string.ascii_letters + string.digits
 8 code = random.sample(str_source, 6)
 9 for i in code:
10     print(i, end="")

输出结果:

1 0sHxSZ

方式二:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import random
 5 
 6 check_code = ""
 7 for i in range(6):
 8     current = random.randrange(0, 6)
 9     if current != i:
10         temp = chr(random.randint(65, 90))
11     else:
12         temp = random.randint(0, 9)
13     check_code += str(temp)
14 print(check_code)

输出结果:

1 HY5YNN

3)os

os.name

输出字符串指示正在使用的平台。

若是是window 则用'nt'表示:

1 >>> import os
2 >>> os.name
3 'nt'

对于Linux/Unix用户,它是'posix':

1 >>> import os
2 >>> os.name
3 'posix'

os.getcwd()

获取当前工做目录,即当前 python 脚本工做的目录路径

1 >>> import os
2 >>> os.getcwd()
3 '/home/test'

os.chdir("dirname")

改变当前脚本工做目录,至关于shell下cd

1 >>> import os
2 >>> os.getcwd()
3 '/home/test'
4 >>> os.chdir("Python35")
5 >>> os.getcwd()
6 '/usr/local/python35'

os.curdir

返回当前目录: ('.')

1 >>> import os
2 >>> os.curdir
3  '.'

os.pardir

获取当前目录的父目录字符串名:('..')

1 >>> import os
2 >>> os.pardir
3 '..'

os.makedirs('dirname1/dirname2')

可生成多层递归目录

 1 >>> import os
 2 >>> os.getcwd()
 3 '/home/test'
 4 >>> os.makedirs('test1/test2')
 5 >>> os.chdir('test1')
 6 >>> os.getcwd()
 7 '/home/test/test1'
 8 >>> os.chdir('test2')
 9 >>> os.getcwd()
10 '/home/test/test1/test2'

os.removedirs('dirname1')

若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推

 1 >>> import os
 2 >>> os.getcwd()
 3 '/home/test/test1/test2'
 4 >>> os.chdir('..')
 5 >>> os.getcwd()
 6 '/home/test/test1'
 7 >>> os.removedirs('test2')
 8 >>> os.getcwd()
 9 '/home/test/test1'
10 >>> os.chdir('test2')
11 Traceback (most recent call last):
12   File "<stdin>", line 1, in <module>
13 OSError: [Errno 2] No such file or directory: 'test2'

os.mkdir('dirname')

生成单级目录,至关于 shell 中 mkdir dirname

 1 >>> import os
 2 >>> os.getcwd()
 3 '/home/test'
 4 >>> os.chdir('test1')
 5 >>> os.getcwd()
 6 '/home/test/test1'
 7 >>> os.listdir('.')
 8 []
 9 >>> os.mkdir('test2')
10 >>> os.listdir('.')
11 ['test2']

os.listdir('dirname')

列出指定目录下的全部文件和子目录,包括隐藏文件,并以列表方式打印

1 >>> import os
2 >>> os.listdir('.')
3 ['.zshrc', '.subversion', '.dbshell', '.mozilla', '.bash_logout', '.gnome2', '.bash_history', '.bashrc', 'test1', '.viminfo', '.emacs', '.bash_profile']

os.rmdir('dirname')

删除单级空目录,若目录不为空则没法删除,报错;至关于shell中rmdir dirname

1 >>> import os
2 >>> os.getcwd()
3 '/home/test/test1'
4 >>> os.listdir('.')
5 ['test2']
6 >>> os.rmdir('test2')
7 >>> os.listdir('.')
8 []

os.remove()

删除一个文件

1 >>> import os
2 >>> os.listdir('.')
3 ['test.log']
4 >>> os.remove('test.log')
5 >>> os.listdir('.')
6 []

os.rename("oldname","newname")

重命名文件/目录

1 >>> import os
2 >>> os.listdir('.')
3 ['test.log']
4 >>> os.rename('test.log','hello.txt')
5 >>> os.listdir('.')
6 ['hello.txt']

os.stat('path/filename')

获取文件/目录信息

1 >>> import os
2 >>> os.listdir('.')
3 ['hello.txt']
4 >>> os.stat('hello.txt')
5 posix.stat_result(st_mode=33188, st_ino=2629852, st_dev=64768L, st_nlink=1, st_uid=505, st_gid=301, st_size=0, st_atime=1478588652, st_mtime=1478588652, st_ctime=1478588686)

os.sep

输出操做系统特定的路径分隔符

win下为"\\"

1 >>> import os
2 >>> os.sep
3 '\\'

Linux下为"/"

>>> import os
>>> os.sep
'/'

os.linesep

输出当前平台使用的行终止符

win下为"\r\n"

1 >>> import os
2 >>> os.linesep
3 '\r\n'

Linux下为"\n"

1 >>> import os
2 >>> os.linesep
3 '\n'

os.pathsep

输出用于分割文件路径的字符串

win下为';'

1 >>> import os
2 >>> os.pathsep
3 ';'

Linux下为':'

1 >>> import os
2 >>> os.pathsep
3 ':'

os.system("bash command")

运行shell命令,直接显示

1 >>> import os
2 >>> os.system('date')
3 Tue Nov  8 15:15:26 CST 2016
4 0

os.environ

获取系统环境变量

1 >>> import os
2 >>> os.environ
3 environ({'OS': 'Windows_NT', 'PROCESSOR_REVISION': '1706', 'HOMEPATH': '\\Users\\test', 'APPDATA': 'C:\\Users\\test\\AppData\\Roaming', 'PUBLIC': 'C:\\Users\\Public', 'PROGRAMFILES(X86)': 'C:\\Program Files (x86)', 'COMPUTERNAME': 'TEST-PC', 'SYSTEMDRIVE': 'C:', 'LOCALAPPDATA': 'C:\\Users\\test\\AppData\\Local', 'COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files', 'SESSIONNAME': 'Console', 'FP_NO_HOST_CHECK': 'NO', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 23 Stepping 6, GenuineIntel', 'PROGRAMDATA': 'C:\\ProgramData', 'USERNAME': 'test','PROGRAMFILES': 'C:\\Program Files', 'CATALINA_HOME': 'D:\\apache-tomcat-6.0.45', 'NUMBER_OF_PROCESSORS': '2', 'TMP': 'C:\\Users\\test\\AppData\\Local\\Temp','PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW', 'PROMPT': '$P$G', 'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files', 'COMSPEC': 'C:\\Windows\\system32\\cmd.exe', 'PROGRAMW6432': 'C:\\Program Files', 'SYSTEMROOT': 'C:\\Windows', 'PATH': 'D:\\Python35\\Scripts\\;D:\\Python35\\;D:\\oracle\\product\\10.2.0\\client_1\\bin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;D:\\Program Files\\TortoiseSVN\\bin;C:\\Redis\\;C:\\Java\\jdk1.6\\bin;D:\\MongoDB\\Server\\3.2\\bin', 'TEMP': 'C:\\Users\\test\\AppData\\Local\\Temp', 'USERDOMAIN': 'test-PC', 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'PROCESSOR_LEVEL': '6', 'PSMODULEPATH': 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\;C:\\Program Files\\Intel\\', 'USERPROFILE': 'C:\\Users\\test', 'ALLUSERSPROFILE': 'C:\\ProgramData', 'LOGONSERVER': '\\\\TEST-PC', 'WINDIR': 'C:\\Windows', 'JAVA_HOME': 'C:\\Java\\jdk1.6', 'HOMEDRIVE': 'C:', 'PROCESSOR_ARCHITECTURE': 'AMD64'})

os.path.abspath(path)

返回path规范化的绝对路径

1 >>> import os
2 >>> os.path.abspath('test1')
3 '/home/test/test1/test1'

os.path.split(path)

将path分割成目录和文件名二元组返回

1 >>> import os
2 >>> os.path.split('/home/test')
3 ('/home', 'test')

os.path.dirname(path)

返回 path 的目录,其实就是os.path.split(path)的第一个元素

1 >>> import os
2 >>> os.path.dirname('/home/test')
3  '/home'

os.path.basename(path)

返回path最后的文件名,若是 path 以 / 或 \ 结尾,那么就会返回空值,即os.path.split(path)的第二个元素

1 >>> import os
2 >>> os.path.basename('home/test')
3 'test'
4 >>> os.path.basename('home/test/')
5 ''

os.path.exists(path)

若是path存在,返回True;若是path不存在,返回False

1 >>> import os
2 >>> os.getcwd()
3 '/home/test/test1'
4 >>> os.listdir('.')
5 ['test2', 'hello.txt']
6 >>> os.path.exists('test1')
7 False
8 >>> os.path.exists('test2')
9 True

os.path.isabs(path)

若是path是绝对路径,返回True

1 >>> import os
2 >>> os.path.isabs('/home/test/test1')
3 True
4 >>> os.path.isabs('test1')
5 False

os.path.isfile(path)

若是path是一个存在的文件,返回True。不然返回False

1 >>> import os
2 >>> os.listdir('.')
3 ['test2', 'hello.txt']
4 >>> os.path.isfile('hello.txt')
5 True
6 >>> os.path.isfile('test.log')
7 False

os.path.isdir(path)

若是path是一个存在的目录,则返回True。不然返回False

1 >>> import os
2 >>> os.listdir('.')
3 ['test2', 'hello.txt']
4 >>> os.path.isdir('test2')
5 True
6 >>> os.path.isdir('hello.txt')
7 False

os.path.join(path1[, path2[, ...]])

将多个路径组合后返回,第一个绝对路径以前的参数将被忽略

1 >>> import os
2 >>> os.path.join('test1','test2','test')
3 'test1/test2/test'
4 >>> os.path.join('/home/test/test1','test2','test')
5 '/home/test/test1/test2/test'
6 >>> os.path.join('test1','/home/test/test1/test2','test')
7 '/home/test/test1/test2/test'

os.path.getatime(path)

返回path所指向的文件或者目录的最后存取时间

1 >>> import os
2 >>> os.listdir('.')
3 ['test2', 'hello.txt']
4 >>> os.path.getatime('hello.txt')
5 1478588652.6452732

os.path.getmtime(path)

返回path所指向的文件或者目录的最后修改时间

1 >>> import os
2 >>> os.listdir('.')
3 ['test2', 'hello.txt']
4 >>> os.path.getmtime('hello.txt')
5 1478588652.6452732

os.path.split(path)

返回一个路径的目录名和文件名

1 >>> import os
2 >>> os.path.split('/home/test/test1/hello.txt')
3 ('/home/test/test1', 'hello.txt')

os.path.getsize(name)

得到文件大小

1 >>> import os
2 >>> os.listdir('.')
3 ['test2', 'hello.txt']
4 >>> os.path.getsize('hello.txt')
5 12
6 >>> os.path.getsize('test2')
7 4096

4)sys

sys.argv

在外部向程序内部传递参数,以list的形式返回参数列表

1 >>> import sys
2 >>> sys.argv
3 ['']

示例:

1 #!/usr/bin/env python
2 # -*- coding:UTF-8 -*-
3 
4 import sys
5 
6 print(sys.argv[0])
7 print(sys.argv[1])

运行结果:

1 $ python sys.py argv1
2 sys.py
3 argv1

sys.exit(n)

执行到主程序末尾,解释器自动退出,可是若是须要中途退出程序,能够调用sys.exit函数,带有一个可选的整数参数返回给调用它的程序,表示你能够在主程序中捕获对sys.exit的调用。(0是正常退出,其余为异常)

1 >>> import sys
2 >>> sys.exit(1)
3 [root@test ~]$ echo $?
4 1

sys.version

获取Python解释程序的版本信息

1 >>> import sys
2 >>> sys.version
3 '3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)]'

sys.maxint

获取最大的int值

1 >>> import sys
2 >>> sys.maxint
3 9223372036854775807

sys.path

返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
>>> import sys
>>> sys.path
['', '/usr/local/python35/lib/python35.zip', '/usr/local/python35/lib/python3.5', '/usr/local/python35/lib/python3.5/plat-linux', '/usr/local/python35/lib/python3.5/lib-dynload', '/usr/local/python35/lib/python3.5/site-packages']

sys.platform

返回操做系统平台名称
1 >>> import sys
2 >>> sys.platform
3 'linux'
sys.modules
sys.modules是一个全局字典,该字典是python启动后就加载在内存中。每当程序员导入新的模块, sys.modules将自动记录该模块。当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。它拥有字典所拥有的一切方法。
1 >>> import sys
2 >>> sys.modules
3 {'_sitebuiltins': <module '_sitebuiltins' from '/usr/local/python35/lib/python3.5/_sitebuiltins.py'>, 'encodings.aliases': <module 'encodings.aliases' from '/usr/local/python35/lib/python3.5/encodings/aliases.py'>, 'errno': <module 'errno' (built-in)>, '_collections_abc': <module '_collections_abc' from '/usr/local/python35/lib/python3.5/_collections_abc.py'>, 'atexit': <module 'atexit' (built-in)>, 'posixpath': <module 'posixpath' from '/usr/local/python35/lib/python3.5/posixpath.py'>, '_codecs': <module '_codecs' (built-in)>, '__main__': <module '__main__' (built-in)>, 'builtins': <module 'builtins' (built-in)>, 'io': <module 'io' from '/usr/local/python35/lib/python3.5/io.py'>, 'genericpath': <module 'genericpath' from '/usr/local/python35/lib/python3.5/genericpath.py'>, 'site': <module 'site' from '/usr/local/python35/lib/python3.5/site.py'>, '_io': <module 'io' (built-in)>, '_frozen_importlib_external': <module '_frozen_importlib_external' (frozen)>, '_stat': <module '_stat' (built-in)>, '_thread': <module '_thread' (built-in)>, 'encodings.latin_1': <module 'encodings.latin_1' from '/usr/local/python35/lib/python3.5/encodings/latin_1.py'>, 'encodings.utf_8': <module 'encodings.utf_8' from '/usr/local/python35/lib/python3.5/encodings/utf_8.py'>, '_imp': <module '_imp' (built-in)>, 'os': <module 'os' from '/usr/local/python35/lib/python3.5/os.py'>, '_weakref': <module '_weakref' (built-in)>, 'zipimport': <module 'zipimport' (built-in)>, 'posix': <module 'posix' (built-in)>, 'stat': <module 'stat' from '/usr/local/python35/lib/python3.5/stat.py'>, 'os.path': <module 'posixpath' from '/usr/local/python35/lib/python3.5/posixpath.py'>, 'codecs': <module 'codecs' from '/usr/local/python35/lib/python3.5/codecs.py'>, 'abc': <module 'abc' from '/usr/local/python35/lib/python3.5/abc.py'>, '_frozen_importlib': <module '_frozen_importlib' (frozen)>, 'encodings': <module 'encodings' from '/usr/local/python35/lib/python3.5/encodings/__init__.py'>, 'marshal': <module 'marshal' (built-in)>, '_signal': <module '_signal' (built-in)>, '_weakrefset': <module '_weakrefset' from '/usr/local/python35/lib/python3.5/_weakrefset.py'>, 'sys': <module 'sys' (built-in)>, 'sysconfig': <module 'sysconfig' from '/usr/local/python35/lib/python3.5/sysconfig.py'>, '_warnings': <module '_warnings' (built-in)>, '_sysconfigdata': <module '_sysconfigdata' from '/usr/local/python35/lib/python3.5/_sysconfigdata.py'>}
sys.stdout.write('please:')
1 >>> import sys
2 >>> sys.stdout.write('please:')
3 please:7

val = sys.stdin.readline()[:-1]

1 >>> import sys
2 >>> val = sys.stdin.readline()[:-1]
3 Hello World
4 >>> val
5 'Hello World'

5)shutil

高级的对文件、文件夹、压缩包处理的模块

 copyfile( src, dst)  从源src复制到dst中去。固然前提是目标地址是具有可写权限。抛出的异常信息为IOException. 若是当前的dst已存在的话就会被覆盖掉
 copymode( src, dst)  只是会复制其权限其余的东西是不会被复制的
 copystat( src, dst)  复制权限、最后访问时间、最后修改时间
 copy( src, dst)     复制一个文件到一个文件或一个目录
 copy2( src, dst)   在copy上的基础上再复制文件最后访问时间与修改时间也复制过来了,相似于cp –p的东西
 copy2( src, dst)   若是两个位置的文件系统是同样的话至关因而rename操做,只是更名;若是是不在相同的文件系统的话就是作move操做
 copytree(olddir,newdir,True/Flase)  把olddir拷贝一份newdir,若是第3个参数是True,则复制目录时将保持文件夹下的符号链接,若是第3个参数是False,则将在复制的目录下生成物理副原本替代符号链接

shutil.copyfileobj(fsrc, fdst[, length])

将文件内容拷贝到另外一个文件中,能够部份内容

  View Code

shutil.copyfile(src, dst)
拷贝文件

  View Code

shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变

  View Code

shutil.copystat(src, dst)
拷贝状态的信息,包括:mode bits, atime, mtime, flags

  View Code

shutil.copy(src, dst)
拷贝文件和权限

  View Code

shutil.copy2(src, dst)
拷贝文件和状态信息

  View Code

shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件

例如:copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))

  View Code

shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件

  View Code

shutil.move(src, dst)
递归的去移动文件

  View Code

shutil.make_archive(base_name, format,...)

建立压缩包并返回文件路径,例如:zip、tar

  • base_name: 压缩包的文件名,也能够是压缩包的路径。只是文件名时,则保存至当前目录,不然保存至指定路径,
    如:www                        =>保存至当前路径
    如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
  • format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
  • root_dir: 要压缩的文件夹路径(默认当前目录)
  • owner: 用户,默认当前用户
  • group: 组,默认当前组
  • logger: 用于记录日志,一般是logging.Logger对象
1
2
3
4
5
6
7
8
9
#将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录
 
import  shutil
ret  =  shutil.make_archive( "wwwwwwwwww" 'gztar' , root_dir = '/Users/wupeiqi/Downloads/test' )
 
 
#将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录
import  shutil
ret  =  shutil.make_archive( "/Users/wupeiqi/wwwwwwwwww" 'gztar' , root_dir = '/Users/wupeiqi/Downloads/test' )
  View Code

shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:

  zipfile 压缩解压
  tarfile 压缩解压
  ZipFile
  TarFile 

 

6)json & pickle

用于序列化的两个模块

  • json,用于字符串和 python 数据类型间进行转换
  • pickle,用于 python 特有的类型和 python 数据类型间进行转换

Json 模块提供了四个功能:dumps、dump、loads、load

pickle 模块提供了四个功能:dumps、dump、loads、load

 

JSON 模块

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成,它基于 JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999 的一个子集。 JSON采用彻底独立于语言的文本格式,可是也使用了相似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。

Python3 中可使用 json 模块来对 JSON 数据进行编解码,它包含了两个函数:

  1. json.dumps():对数据进行编码
  2. json.loads():对数据进行解码

json.dumps与json.loads实例

1 #!/usr/bin/env python
2 # -*- coding:UTF-8 -*-
3 
4 import json
5 # 将python的基础数据类型转化成字符串
6 dic = {"k1": "v1", "k2": "v2"}
7 print("Python原始数据:", repr(dic), type(dic))
8 result = json.dumps(dic)    # 将字典类型转换为字符串类型
9 print("JSON对象:", result, type(result))

输出结果:

1 Python原始数据: {'k2': 'v2', 'k1': 'v1'} <class 'dict'>
2 JSON对象: {"k2": "v2", "k1": "v1"} <class 'str'>

JSON 编码的字符串转换回 Python 数据结构

 1 #!/usr/bin/env python
 2 # -*- coding:UTF-8 -*-
 3 
 4 import json
 5 # 将 python 的基础数据类型转化成字符串
 6 dic = {"k1": "v1", "k2": "v2"}
 7 print("Python原始数据:", repr(dic), type(dic))
 8 result = json.dumps(dic)    # 将字典类型转换为字符串类型
 9 print("JSON对象:", result, type(result))
10 
11 # 将 python 字符串类型转化为 python 基本数据类型
12 result = json.loads(result)
13 print("result['k1']:", result['k1'])
14 print("result['k2']:", result['k2'])

输出结果:

1 Python原始数据: {'k1': 'v1', 'k2': 'v2'} <class 'dict'>
2 JSON对象: {"k1": "v1", "k2": "v2"} <class 'str'>
3 result['k1']: v1
4 result['k2']: v2

若是要处理的是文件而不是字符串,可使用 json.dump() 和 json.load() 来编码和解码JSON数据

 1 #!/usr/bin/env python
 2 # -*- coding:UTF-8 -*-
 3 
 4 import json
 5 
 6 data = {
 7     'name': "James",
 8     'age': 24,
 9     'job': "IT"
10 }
11 # 写入 json 数据
12 with open('db.json', 'w', encoding="UTF-8") as f:
13     json.dump(data, f)
14 
15 # 读取json数据
16 with open('db.json', 'r', encoding="UTF-8") as f:
17     res = json.load(f)
18     print(res,type(res))

输出结果:

1 {'name': 'James', 'age': 24, 'job': 'IT'} <class 'dict'>

PICKLE 模块

pickle 模块使用的数据格式是 python 专用的,而且不一样版本不向后兼容,同时也不能被其余语言说识别。要和其余语言交互,可使用内置的 json 包使用 pickle 模块你能够把Python对象直接保存到文件,而不须要把他们转化为字符串,也不用底层的文件访问操做把它们写入到一个二进制文件里。 pickle模块会建立一个python语言专用的二进制格式,基本上不用考虑任何文件细节,它会帮你干净利落地完成读写独享操做,惟一须要的只是一个合法的文件句柄。

python3中可使用pickle模块,对数据进行编解码。它包含两个函数:

  1. pickle.dumps()
  2. pickle.loads()

pickle.dumps与pickle.loads实例

 1 #!/usr/bin/env python
 2 # -*- coding:UTF-8 -*-
 3 
 4 import pickle
 5 
 6 data = {
 7     'name': "James",
 8     'age': 24,
 9     'job': "IT"
10 }
11 
12 print("原始python对象:", repr(data))
13 r = pickle.dumps(data)
14 print("pickle转换后的对象:", r)
15 res = pickle.loads(r)
16 print("res['name']:", res['name'])
17 print("res['age']:", res['age'])
18 print("res['job']:", res['job'])

输出结果:

1 原始python对象: {'name': 'James', 'job': 'IT', 'age': 24}
2 pickle转换后的对象: b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x05\x00\x00\x00Jamesq\x02X\x03\x00\x00\x00jobq\x03X\x02\x00\x00\x00ITq\x04X\x03\x00\x00\x00ageq\x05K\x18u.'
3 res['name']: James
4 res['age']: 24
5 res['job']: IT

若是要处理的是文件而不是字符串,你可使用 pickle.dump() 和 pickle.load() 来编码和解码JSON数据

 1 #!/usr/bin/env python
 2 # -*- coding:UTF-8 -*-
 3 
 4 import pickle
 5 
 6 data = {
 7     'name': "James",
 8     'age': 24,
 9     'job': "IT"
10 }
11 # 写入数据,要以wb格式写入
12 pickle.dump(data, open('db', 'wb'))
13 # 读取数据,要以rb格式读取
14 f = open('db', 'rb')
15 res = pickle.load(f)
16 print(res)

输出结果:

1 {'name': 'James', 'age': 24, 'job': 'IT'}

pickle和json的区别:

  • json 适合跨语言,对于 python 而言仅适用于 Python 基本数据类型
  • pickle 仅适用于 python,pickle 适用于 python 全部数据类型的序列化
  • pickle 写入和读取文件时,用的是 ‘b’模式,而 json 没有。
  • json 只能序列化最基本的数据类型,而 pickle 能够序列化全部的数据类型,包括类,函数均可以序列化。

7)shelve

8)xml 处理

9)yaml 处理

10)configparser

11) hashlib

12) subprocess

subprocess模块是子进程管理器,用户来生成子进程,并能够经过管道链接他们的输入、输出、错误,以及获取它们的返回值。
subprocess模块用来代替多个旧模块和函数,例如:

  • os.system
  • os.spawn*
  • os.popen*
  • popen2.*
  • commands.*

subprocess.call

语法:
     subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
语义:
     运行由args指定的命令,直到命令结束后,返回返回码的属性值。

上面的参数是最多见的方式,下面是示例代码:
>>>
>>> subprocess.call(["ls", "-l"])
0
>>> subprocess.call("exit 1", shell=True)
1
使用 shell=True 是一种安全保护机制。
在使用这个函数时,不要使用 stdout=PIPE 或 stderr=PIPE 参数,否则会致使子进程输出的死锁。
若是要使用管道,能够在 communicate()方法中使用Popen
示例代码:
import subprocess
rc = subprocess.call(["ls","-l"])

能够经过一个shell来解释一整个字符串:
import subprocess
out = subprocess.call("ls -l", shell=True)
out = subprocess.call("cd ..", shell=True)

使用了shell=True这个参数。
这个时候,咱们使用一整个字符串,而不是一个表来运行子进程。
Python将先运行一个shell,再用这个shell来解释这整个字符串。

shell命令中有一些是shell的内建命令,这些命令必须经过shell运行,$cd。
shell=True容许咱们运行这样一些命令。

2. subprocess.check_call

语法: 
     subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False)
语义:
     运行由args指定的命令,直到命令执行完成。
     若是返回码为零,则返回。不然,抛出 CalledProcessError异常。
     CalledProcessError对象包含有返回码的属性值。

上面显示的参数仅仅是最多见的,下面是用户更经常使用的参数。
示例代码以下:
>>>
>>> subprocess.check_call(["ls", "-l"])
0
>>> subprocess.check_call("exit 1", shell=True)
Traceback (most recent call last):
   ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

这个函数在python 2.5版本中引入。
WARNING: 使用 shell=True 是一种安全机制。
NOTE: 不要在这个函数中使用 stdout=PIPE 或 stderr=PIPE, 不然会形成子进程死锁。
      若是须要使用管道,能够在 communicate()方法中使用Popen.

3. subprocess.check_output

语法: 
      subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)
语义:
     运行args定义的命令,并返回一个字符串表示的输出值。
     若是返回码为非零,则抛出 CalledProcessError异常。
示例代码:
>>>
>>> subprocess.check_output(["echo", "Hello World!"])
'Hello World!\n'
>>> subprocess.check_output("exit 1", shell=True)
Traceback (most recent call last):
   ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
若是要捕捉结果中的标准错误,使用 stderr=subprocess.STDOUT参数:
>>>
>>> subprocess.check_output(
...     "ls non_existent_file; exit 0",
...     stderr=subprocess.STDOUT,
...     shell=True)
'ls: non_existent_file: No such file or directory\n'
这个函数在python 2.7版本中引入。
WARNING: 使用 shell=True 是一种安全机制。
NOTE: 不要在这个函数中使用 stdout=PIPE 或 stderr=PIPE, 不然会形成子进程死锁。
      若是须要使用管道,能够在 communicate()方法中使用Popen.

4. subprocess.PIPE

   使用Popen时,用于 stdin, stdout和stderr参数的特殊值,表示打开链接标准流的管道。

5. subprocess.STDOUT

   使用Popen时,用于 stderr 参数的特殊值,表示将标准错误重定向到标准输出的同一个句柄。

6. 异常 subprocess.CalledProcessError

   当由 check_call()或 check_output()运行的进程返回非零状态值时抛出的异常。

7. returncode

   子进程的退出状态。

8. cmd

   子进程执行的命令。

9. output

   若是check_output()抛出异常时,子进程的输出值。
   不然,没有这个值。

1.1.1. 经常使用的参数

为了支持各类用户使用状况 ,Popen构建函数接收多种可选参数。
对于最典型的状况,许多参数都保留有安全的默认值,这些最经常使用的方式以下:

1. args

全部的函数都须要这个参数,而且它是一个字符串,或者是程序的参数序列。
提供一个参数序列是更推荐的方式,由于这样能容许模块接收空格 或 引号中的参数。
若是传递的是单个字符串,要么 shell=True, 或都要么 字符串就程序名字,而且不能带参数。

2. stdin, stdout 和 stderr

stdin, stdout和stderr指定了执行程序的标准输入,标准输出和标准错误的文件句柄。
它们的值能够是PIPE, 一个存在的文件描述符(正整数),一个存在的文件对象,或 None.
PIPE 表示建立一个链接子进程的新管道。
默认值 为 None, 表示不作重定向。
子进程的文件句柄能够从父进程中继承获得。
另外,stderr能够设置值为 STDOUT,表示子进程的错误数据能够和标准输出是同一个文件句柄。

当stdout 或 stderr的值为管道 而且  universal_newlines的值为真时,
对于以 ‘U'模式参数打开的新行,全部行的结束都会转换成'\n'。

3. shell

若是 shell的值为 True, 则指定的命令行会经过shell来执行。
若是你使用Python来做为流程控制,那这样的设置会颇有用,由于它提供了绝大多数的系统shell命令且能够很方便地使用
shell的各类功能,如 shell 管道,文件名通配符,环境变量扩展,以及用户目录扩展符 ~。
可是,须要注意的是,Python 提供了相似shell功能的实现。

WARNING: 执行不受信任来源的shell命令会是一个严重的安全问题。
         基于这一点,shell=True 是不建议的。
示例代码以下:
>>>
>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...

shell=False 关闭了shell的全部基本功能 ,从而不会有上面所说的安全漏洞。
能够在Popen构建函数的帮助文档中看到,它只有在 shell=False时才能工做。
当使用  shell=True时,pipes.quote()能够被用于转译空格,shell的字符等。

1.1.2. Popen构建函数

subprocess中更底层的进程建立和管理能够经过Popen类实现。
它提供了更多的灵活性,程序员经过它能处理更多复杂的状况。
语法:
     class subprocess.Popen(args, bufsize=0, executable=None, 
                            stdin=None, stdout=None, stderr=None, 
                            preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None,
                            universal_newlines=False, startupinfo=None, creationflags=0)
语义:
     在新进程中执行一个子程序。
     在Unix中,这个类使用 相似于 os.execvp()方式来执行子程序。
     在Windows中,这个类使用Windows的 CreateProcess()函数来执行子程序。
参数解析:
args: 一个程序参数序列,或者单个字符串。
      默认的,要执行的程序应该是序列的第一个字段。
      若是单个字符串,它的解析依赖于平台
在Unix中,若是 args是一个字符串,那么这个字符串解释成被执行程序的名字或路径。
然而,这种状况只能用在不须要参数的程序。

NOTE: 当对args肯定了正确的分隔符后,shlex.split()就颇有用,特别是在复杂的状况下:
>>>
>>> import shlex, subprocess
>>> command_line = raw_input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print args
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!

NOTE: 选项(如 -input) 和 参数(如 eggs.txt) 在shell中是用空格分隔成分离的列表元素。
      若是参数须要引号或反斜线,则它们会是一个单一列表元素。
shell参数(默认值为False)声明了是否使用shell来执行程序。
若是 shell=True, 它将args看做是一个字符串,而不是一个序列。

在Unix系统,且 shell=True时,shell默认使用 /bin/sh.
若是 args是一个字符串,则它声明了经过shell执行的命令。这意味着,字符串必需要使用正确的格式。
若是 args是一个序列,则第一个元素就是命令字符串,而其它的元素都做为参数使用。
能够这样说,Popen等价于:
      Popen(['/bin/sh', '-c', args[0], args[1], ...])
bufsize: 若是指定了值,则它和内建函数 open()对应的参数有相同的意义:
         0 -- 表示不缓冲
         1 -- 表示缓冲
         任何其它的正数值表示buffer的大小。
         负数值表示使用系统默认值,一般表示彻底缓冲。
         它的默认值为零。
NOTE: 若是遇到性能问题,建议将bufsize设置成 -1 或足够大的正数(如 4096)。

executable: 指定了用于代替执行的程序。它极少会用到。
stdin, stdout, stderr:指定了执行程序的标准输入,标准输出和标准错误的文件句柄。
         有效的值能够是 PIPE, 一个存在的文件描述符,或存在的文件对象,或 None.
         默认值为 None。 
         stderr能够设置成STDOUT, 它表示将子进程的stderr数据重定向到stdout.
preexec_fn: 若是它被设置成可调用对象,那么这个对象会在子进程执行前被子进程调用,只用于Unix.
close_fds:  若是设置为True, 则在子进程被执行前,除0,1和2以外的全部文件描述符都将被关闭,只用于Unix。
cwd: 当它不为 None时,子程序在执行前,它的当前路径会被替换成 cwd的值。
     这个路径并不会被添加到可执行程序的搜索路径,因此cwd不能是相对路径。
env: 当它不为 None时,它是新进程的环境变量的映射。
     能够用它来代替当前进程的环境。 
universal_newlines: 为真时,文件对象 stdout和 stderr都被以文本文件的方式打开

示例代码:
1. Popen对象建立后,主程序不会自动等待子进程完成。
咱们必须调用对象的wait()方法,父进程才会等待 (也就是阻塞block):
    import subprocess
    child = subprocess.Popen(["ping","-c","5","www.google.com"])
    print("parent process")

从运行结果中看到,父进程在开启子进程以后并无等待child的完成,而是直接运行print。

2. 对比等待的状况:
   import subprocess
   child = subprocess.Popen(["ping","-c","5","www.google.com"])
   child.wait()
   print("parent process")

此外,你还能够在父进程中对子进程进行其它操做,好比咱们上面例子中的child对象:
child.poll()           # 检查子进程状态
child.kill()           # 终止子进程
child.send_signal()    # 向子进程发送信号
child.terminate()      # 终止子进程
子进程的PID存储在child.pid

3. 能够在Popen()创建子进程的时候改变标准输入、标准输出和标准错误,
并能够利用subprocess.PIPE将多个子进程的输入和输出链接在一块儿,构成管道(pipe):
    import subprocess
    child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
    child2 = subprocess.Popen(["wc"], stdin=child1.stdout,stdout=subprocess.PIPE)
    out = child2.communicate()
    print(out)

subprocess.PIPE实际上为文本流提供一个缓存区。
child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。
child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
要注意的是,communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。

4. 还能够利用communicate()方法来使用PIPE给子进程输入:
    import subprocess
    child = subprocess.Popen(["cat"], stdin=subprocess.PIPE)
    child.communicate("vamei")
咱们启动子进程以后,cat会等待输入,直到咱们用communicate()输入"vamei"。

经过使用subprocess包,咱们能够运行外部程序。这极大的拓展了Python的功能。
若是你已经了解了操做系统的某些应用,你能够从Python中直接调用该应用(而不是彻底依赖Python),
并将应用的结果输出给Python,并让Python继续处理。
shell的功能(好比利用文本流链接各个应用),就能够在Python中实现。

1.1.3.异常

在开始执行新程序以前,子进程抛出的异常,会被从新抛出到父进程。
另外,异常对象会有一个额外的属性,叫作 child_traceback, 它是一个字符串,包含从子程序的观察点追踪到的信息。

最多见的抛出的异常是 OSError, 当它发生时,一般是咱们执行了一个不存在的文件。应用程序应当要能处理这个异常。
若是使用无效的参数调用 Popen,会抛出 ValueError异常。
若是被调用进程的返回码不为零,则check_call()和check_output()会抛出 CalledProcessError异常。

1.1.4. 安全

Unlike some other popen functions, this implementation will never call a system shell implicitly. 
This means that all characters, including shell metacharacters, can safely be passed to child processes. 
Obviously, if the shell is invoked explicitly, then it is the application’s responsibility to ensure that 
all whitespace and metacharacters are quoted appropriately.

13) logging

将日志打印到屏幕

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import logging
 5 
 6 logging.debug("This is debug message.")
 7 logging.info("This is info message.")
 8 logging.warn("This warning message.")
 9 logging.error("This is error message.")
10 logging.critical("This is critical message.")

输出结果:

1 WARNING:root:This warning message.
2 ERROR:root:This is error message.
3 CRITICAL:root:This is critical message.

默认状况下,logging将日志打印到屏幕,日志级别为warning。

日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG

经过 logging.basicConfig 函数对日志的输出格式及方式作相关配置

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import logging
 5 
 6 logging.basicConfig(level=logging.DEBUG,
 7                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
 8                     datefmt='%a, %d %b %Y %H:%M:%S',
 9                     filename='mylog.log',
10                     filemode='w')
11 
12 logging.debug("This is debug message.")
13 logging.info("This is info message.")
14 logging.warn("This warning message.")
15 logging.error("This is error message.")
16 logging.critical("This is critical message.")

输出文件中的内容为:

1 Fri, 18 Nov 2016 23:19:16 re_module.py[line:12] DEBUG This is debug message.
2 Fri, 18 Nov 2016 23:19:16 re_module.py[line:13] INFO This is info message.
3 Fri, 18 Nov 2016 23:19:16 re_module.py[line:14] WARNING This warning message.
4 Fri, 18 Nov 2016 23:19:16 re_module.py[line:15] ERROR This is error message.
5 Fri, 18 Nov 2016 23:19:16 re_module.py[line:16] CRITICAL This is critical message.

logging.basicConfig 函数参数说明

  • filename: 指定日志文件名
  • filemode: 和 file 函数意义相同,指定日志文件的打开模式,'w'或'a'
  • format: 指定输出的格式和内容,format能够输出不少有用信息,如上例所示:
    • %(name)s: logger 的名字
    • %(levelno)s: 打印日志级别的数值
    • %(levelname)s: 打印日志级别名称
    • %(pathname)s: 打印当前执行程序的路径,其实就是 sys.argv[0]
    • %(filename)s: 打印当前执行程序名
    • %(funcName)s: 打印日志的当前函数
    • %(lineno)d: 打印日志的当前行号
    • %(asctime)s: 打印字符串形式的日志时间,默认格式是 “2016-11-19 00:06:49,620”,逗号后面的是毫秒
    • %(created)f: 当前时间,用 UNIX 标准的表示时间的浮点数表示
    • %(relativeCreated)d: 输出日志信息时的,自 Logger 建立以来的毫秒数
    • %(thread)d: 打印线程 ID
    • %(threadName)s: 打印线程名称
    • %(process)d: 打印进程 ID
    • %(message)s: 打印日志信息
  • datefmt: 指定时间格式,同 time.strftime()
  • level: 设置日志级别,默认为 logging.WARNING
  • stream: 指定将日志的输出流,能够指定输出到 sys.stderr,sys.stdout 或者文件,默认输出到 sys.stderr,当 stream 和 filenam e同时指定时,stream 被忽略

将日志同时输出到文件和屏幕

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import logging
 5 
 6 logging.basicConfig(level=logging.DEBUG,
 7                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
 8                     datefmt='%a, %d %b %Y %H:%M:%S',
 9                     filename='mylog.log',
10                     filemode='w')
11 
12 ###################################################################################################
13 # 定义一个StreamHandler,将INFO级别或更高的日志信息打印到标准错误,并将其添加到当前的日志处理对象
14 console = logging.StreamHandler()
15 console.setLevel(logging.INFO)
16 formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
17 console.setFormatter(formatter)
18 logging.getLogger('').addHandler(console)
19 ###################################################################################################
20 
21 logging.debug("This is debug message.")
22 logging.info("This is info message.")
23 logging.warn("This warning message.")
24 logging.error("This is error message.")
25 logging.critical("This is critical message.")

输出结果:

1 root        : INFO     This is info message.
2 root        : WARNING  This warning message.
3 root        : ERROR    This is error message.
4 root        : CRITICAL This is critical message.

输出到文件中的内容:

1 Sat, 19 Nov 2016 00:27:17 re_module.py[line:20] DEBUG This is debug message.
2 Sat, 19 Nov 2016 00:27:17 re_module.py[line:21] INFO This is info message.
3 Sat, 19 Nov 2016 00:27:17 re_module.py[line:22] WARNING This warning message.
4 Sat, 19 Nov 2016 00:27:17 re_module.py[line:23] ERROR This is error message.
5 Sat, 19 Nov 2016 00:27:17 re_module.py[line:24] CRITICAL This is critical message.

logging之日志回滚

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import logging
 5 from logging.handlers import RotatingFileHandler
 6 
 7 ###################################################################################################
 8 # 定义一个RotatingFileHandler,最多备份5个日志文件,每一个日志文件最大10M
 9 handler = RotatingFileHandler('mylog.log', maxBytes=10*1024*1024, backupCount=5)
10 handler.setLevel(logging.INFO)
11 formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
12 handler.setFormatter(formatter)
13 logging.getLogger('').addHandler(handler)
14 ###################################################################################################

logging有一个日志处理的主对象,其它处理方式都是经过addHandler添加进去的。

logging的几种handle方式以下:

  • logging.StreamHandler: 日志输出到流,能够是sys.stderr、sys.stdout或者文件
  • logging.FileHandler: 日志输出到文件
  • 日志回滚方式,实际使用时用RotatingFileHandler和TimedRotatingFileHandler
  • logging.handlers.BaseRotatingHandler
  • logging.handlers.RotatingFileHandler
  • logging.handlers.TimedRotatingFileHandler
  • logging.handlers.SocketHandler: 远程输出日志到TCP/IP sockets
  • logging.handlers.DatagramHandler: 远程输出日志到UDP sockets
  • logging.handlers.SMTPHandler: 远程输出日志到邮件地址
  • logging.handlers.SysLogHandler: 日志输出到syslog
  • logging.handlers.NTEventLogHandler: 远程输出日志到Windows NT/2000/XP的事件日志
  • logging.handlers.MemoryHandler: 日志输出到内存中的制定buffer
  • logging.handlers.HTTPHandler: 经过"GET"或"POST"远程输出到HTTP服务器

因为StreamHandler和FileHandler是经常使用的日志处理方式,因此直接包含在logging模块中,而其余方式则包含在logging.handlers模块中

经过logging.config模块配置日志

logger.conf:

 1 #logger.conf
 2 ###############################################
 3 [loggers]
 4 keys=root,example01,example02
 5 [logger_root]
 6 level=DEBUG
 7 handlers=hand01,hand02
 8 [logger_example01]
 9 handlers=hand01,hand02
10 qualname=example01
11 propagate=0
12 [logger_example02]
13 handlers=hand01,hand03
14 qualname=example02
15 propagate=0
16 ###############################################
17 [handlers]
18 keys=hand01,hand02,hand03
19 [handler_hand01]
20 class=StreamHandler
21 level=INFO
22 formatter=form02
23 args=(sys.stderr,)
24 [handler_hand02]
25 class=FileHandler
26 level=DEBUG
27 formatter=form01
28 args=('myapp.log', 'a')
29 [handler_hand03]
30 class=handlers.RotatingFileHandler
31 level=INFO
32 formatter=form02
33 args=('myapp.log', 'a', 10*1024*1024, 5)
34 ###############################################
35 [formatters]
36 keys=form01,form02
37 [formatter_form01]
38 format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
39 datefmt=%a, %d %b %Y %H:%M:%S
40 [formatter_form02]
41 format=%(name)-12s: %(levelname)-8s %(message)s
42 datefmt=

示例一:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import logging
 5 import logging.config
 6 
 7 logging.config.fileConfig("logger.conf")
 8 logger = logging.getLogger("example01")
 9 
10 logger.debug('This is debug message.')
11 logger.info('This is info message.')
12 logger.warn('This is warning message.')

输出结果:

1 example01   : INFO     This is info message.
2 example01   : WARNING  This is warning message.

输出文件内容:

1 Sat, 19 Nov 2016 00:54:02 re_module.py[line:10] DEBUG This is debug message.
2 Sat, 19 Nov 2016 00:54:02 re_module.py[line:11] INFO This is info message.
3 Sat, 19 Nov 2016 00:54:02 re_module.py[line:12] WARNING This is warning message.

示例二:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import logging
 5 import logging.config
 6 
 7 logging.config.fileConfig("logger.conf")
 8 logger = logging.getLogger("example02")
 9 
10 logger.debug('This is debug message.')
11 logger.info('This is info message.')
12 logger.warn('This is warning message.')

输出结果:

1 example02   : INFO     This is info message.
2 example02   : WARNING  This is warning message.

输出文件内容:

1 example02   : INFO     This is info message.
2 example02   : WARNING  This is warning message.

logging是线程安全的

14) re 正则表达式

正则表达式是一个特殊的字符序列,他它能帮你方便的检查一个字符串是否与某种模式匹配。

re 模块使 Python 语言拥有所有的正则表达式功能。

compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。

re 模块也提供了与这些方法功能彻底一致的函数,这些函数使用一个模式字符串作为它们的第一个参数。

re.match 函数

re.match 尝试从字符串的起始位置匹配一个模式,若是不是起始位置匹配成功的话,match() 就返回 none 。

函数语法:

re.match(pattern, string, flags=0)

函数参数说明:

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

匹配成功 re.match 方法返回一个匹配的对象,不然返回None。

可使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。

匹配对象方法 描述
group(num=0) 匹配的整个表达式的字符串,group() 能够一次输入多个组号,在这种状况下它将返回一个包含那些组所对应值的元组
groups() 返回一个包含全部小组字符串的元组,从 1 到 所含的小组号


实例1:

1 >>> import re
2 >>> re.match('www', 'www.chblogs.com') # 在起始位置匹配
3 <_sre.SRE_Match object; span=(0, 3), match='www'>
4 >>> re.match('www', 'www.chblogs.com').span() # 在起始位置匹配
5 (0, 3)
6 >>> re.match('com', 'www.chblogs.com') # 不在起始位置匹配
7 >>> 

实例2:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import re
 5 
 6 line = "Cats are smarter than dogs."
 7 
 8 matchObj = re.match(r'(.*) are (.*) .*', line, re.M|re.I)
 9 
10 if matchObj:
11     print("matchObj.group():", matchObj.group())
12     print("matchObj.group(1):", matchObj.group(1))
13     print("matchObj.group(2):", matchObj.group(2))
14 else:
15     print("No match!")

输出结果:

1 matchObj.group(): Cats are smarter than dogs.
2 matchObj.group(1): Cats
3 matchObj.group(2): smarter than

re.search 方法

re.search 扫描整个字符串并返回第一个成功的匹配。

函数语法:

re.search(pattern, string, flags=0)

函数参数说明:

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等

匹配成功 re.search 方法返回一个匹配的对象,不然返回None。

可使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。

匹配对象方法 描述
group(num=0) 匹配的整个表达式的字符串,group() 能够一次输入多个组号,在这种状况下它将返回一个包含那些组所对应值的元组
groups() 返回一个包含全部小组字符串的元组,从 1 到 所含的小组号

实例1:

1 >>> import re
2 >>> re.search('www', 'www.cnblogs.com')
3 <_sre.SRE_Match object; span=(0, 3), match='www'>
4 >>> re.search('www', 'www.cnblogs.com').span()
5 (0, 3)
6 >>> re.search('com', 'www.cnblogs.com')
7 <_sre.SRE_Match object; span=(12, 15), match='com'>
8 >>> re.search('com', 'www.cnblogs.com').span()
9 (12, 15)

实例2:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import re
 5 
 6 line = "Cats are smarter than dogs."
 7 
 8 searchObj = re.search(r'(.*) are (.*) .*', line, re.M|re.I)
 9 
10 if searchObj:
11     print("searchObj.group():", searchObj.group())
12     print("searchObj.group(1):", searchObj.group(1))
13     print("searchObj.group(2):", searchObj.group(2))
14 else:
15     print("Nothing found!")

输出结果:

1 searchObj.group(): Cats are smarter than dogs.
2 searchObj.group(1): Cats
3 searchObj.group(2): smarter than

re.match与re.search的区别

re.match 只匹配字符串的开始,若是字符串开始不符合正则表达式,则匹配失败,函数返回None;而 re.search 匹配整个字符串,直到找到一个匹配。

实例:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import re
 5 
 6 line = "Cats are smarter than dogs."
 7 
 8 matchObj = re.match(r'dogs', line, re.M|re.I)
 9 if matchObj:
10     print("match --> matchObj.group():", matchObj.group())
11 else:
12     print("No match!")
13 
14 searchObj = re.search(r'dogs', line, re.M|re.I)
15 if searchObj:
16     print("search --> searchObj.group():", searchObj.group())
17 else:
18     print("No match!")

输出结果:

1 No match!
2 search --> searchObj.group(): dogs

检索和替换

Python 的 re 模块提供了re.sub 用于替换字符串中的匹配项。

语法:

re.sub(pattern, repl, string, count=0, flags=0)

参数:

  • pattern : 正则中的模式字符串。
  • repl : 替换的字符串,也可为一个函数。
  • string : 要被查找替换的原始字符串。
  • count : 模式匹配后替换的最大次数,默认 0 表示替换全部的匹配。

实例:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import re
 5 
 6 phone = "2004-959-559 # 这是一个国外电话号码"
 7 
 8 # 删除字符串中的 Python 注释
 9 num = re.sub(r'#.*$', "", phone)
10 print("电话号码是:", num)
11 
12 # 删除非数字(-)的字符串
13 num = re.sub(r'\D', "", phone)
14 print("电话号码是:", num)

输出结果:

1 电话号码是: 2004-959-559 
2 电话号码是: 2004959559

当 repl 参数是一个函数时:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import re
 5 
 6 
 7 # 将匹配的数字乘于 2
 8 def double(matched):
 9     value = int(matched.group('value'))
10     return str(value * 2)
11 
12 s = 'A23G4HFD567'
13 print(re.sub('(?P<value>\d+)', double, s))

输出结果:

1 A46G8HFD1134

正则表达式修饰符 - 可选标志

正则表达式能够包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志能够经过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

修饰符 描述
re.I 使匹配对大小写不敏感
re.L 作本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的全部字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志经过给予你更灵活的格式以便你将正则表达式写得更易于理解。

正则表达式模式

模式字符串使用特殊的语法来表示一个正则表达式:

字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配一样的字符串。

多数字母和数字前加一个反斜杠时会拥有不一样的含义。

标点符号只有被转义时才匹配自身,不然它们表示特殊的含义。

反斜杠自己须要使用反斜杠转义。

因为正则表达式一般都包含反斜杠,因此最好使用原始字符串来表示它们。模式元素(如 r'/t',等价于'//t')匹配相应的特殊字符。

下表列出了正则表达式模式语法中的特殊元素。若是你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

模式 描述
^ 匹配字符串的开头
$ 匹配字符串的末尾
. 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则能够匹配包括换行符的任意字符
[...] 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...] 不在[]中的字符:[^abc] 匹配除了a,b,c以外的字符
re* 匹配0个或多个的表达式
re+ 匹配1个或多个的表达式
re? 匹配0个或1个由前面的正则表达式定义的片断,非贪婪方式
re{n}  精确匹配n个前面表达式
re{n,} 精确匹配n个前面表达式
re{n, m} 匹配 n 到 m 次由前面的正则表达式定义的片断,贪婪方式
a|b 匹配a或b
(re) G匹配括号内的表达式,也表示一个组
(?imx) 正则表达式包含三种可选标志:i, m, 或 x ,只影响括号中的区域
(?-imx) 正则表达式关闭 i, m, 或 x 可选标志,只影响括号中的区域。
(?: re) 相似 (...), 可是不表示一个组
(?imx: re) 在括号中使用i, m, 或 x 可选标志
(?-imx: re) 在括号中不使用i, m, 或 x 可选标志
(?#...) 注释.
(?= re) 前向确定界定符,若是所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,不然失败,但一旦所含表达式已经尝试,匹配引擎根本没有提升;模式的剩余部分还要尝试界定符的右边
(?! re) 前向否认界定符,与确定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
(?> re) 匹配的独立模式,省去回溯
\w 匹配字母数字及下划线
\W 匹配非字母数字及下划线
\s 匹配任意空白字符,等价于 [\t\n\r\f].
\S 匹配任意非空字符
\d 匹配任意数字,等价于 [0-9].
\D 匹配任意非数字
\A 匹配字符串开始
\Z 匹配字符串结束,若是是存在换行,只匹配到换行前的结束字符串。c
\z 匹配字符串结束
\G 匹配最后匹配完成的位置
\b 匹配一个单词边界,也就是指单词和空格间的位置,例如, 'er\b' 能够匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'
\B 匹配非单词边界,'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'
\n, \t, 等. 匹配一个换行符,匹配一个制表符等
\1...\9 匹配第n个分组的子表达式
\10 匹配第n个分组的子表达式,若是它经匹配。不然指的是八进制字符码的表达式

正则表达式实例

字符匹配

实例 描述
python 匹配 "python".

字符类

实例 描述
[Pp]ython 匹配 "Python" 或 "python"
rub[ye] 匹配 "ruby" 或 "rube"
[aeiou] 匹配中括号内的任意一个字母
[0-9] 匹配任何数字。相似于 [0123456789]
[a-z] 匹配任何小写字母
[A-Z] 匹配任何大写字母
[a-zA-Z0-9] 匹配任何字母及数字
[^aeiou] 除了aeiou字母之外的全部字符
[^0-9] 匹配除了数字外的字符

特殊字符类

实例 描述
. 匹配除 "\n" 以外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式
\d 匹配一个数字字符,等价于 [0-9]
\D 匹配一个非数字字符,等价于 [^0-9]
\s 匹配任何空白字符,包括空格、制表符、换页符等等,等价于 [ \f\n\r\t\v]
\S 匹配任何非空白字符,等价于 [^ \f\n\r\t\v]
\w 匹配包括下划线的任何单词字符,等价于'[A-Za-z0-9_]'
\W 匹配任何非单词字符,等价于 '[^A-Za-z0-9_]'

本节做业

开发一个简单的python计算器

  1. 实现加减乘除及拓号优先级解析
  2. 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等相似公式后,必须本身解析里面的(),+,-,*,/符号和公式(不能调用eval等相似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致

 

hint:

re.search(r'\([^()]+\)',s).group()

'(-40/5)'

相关文章
相关标签/搜索