C语言基础学习PYTHON——基础学习D05

 

20180815内容纲要:

    1 模块

    2 包

    3 import的本质

    4 内置模块详解

      (1)time&datetime

      (2)datetime

      (3)random

      (4)os

      (5)sys

      (6)json&pickle

      (7)shelve

      (8)xml

      (9)shutil

      (10)PyYaml

      (11)configpaser

      (12)hashlib

      (13)re

    5 练习:开发一个简单的python计算器(挑战性很强)

      

1 模块

模块:
>>>定义:本质就是.py结尾的PYTHON文件,用来从逻辑上组织python代码(变量、函数、类、逻辑),实现一个功能。

>>>导入方法:

1 import module_name            调用module_name.xxx
2 from module_name import *    直接调用即可(导入优化)
3 from module_name import func_module_name as func    
4 form . improt module_name     从当前目录下导入module_name            

导入方法

>>>模块分类

  • 自定义模块
  • 内置标准模块(又称标准库)
  • 开源模块

自定义模块和开源模块的使用参考      http://www.cnblogs.com/wupeiqi/articles/4963027.html 

2 包

包:用来从逻辑上组织模块,本质就是一个目录,(必须带有一个__init__.py文件),
那么在导入包之后改如何调用包下面的.py文件呢?

1 #Author:ZhangKanghui
2 print("我最美")
3 from . import foo

__init__.py

1 #Author:ZhangKanghui
2 def foo():
3     print("我喜欢你")

foo.py

1 #Author:ZhangKanghui
2 import package
3 
4 package.foo.foo()

调用(必须与包在同级目录下)

 

3 import的本质

import的本质(路径搜索和搜索路径):
  >>>导入模块的本质就是把python文件解释一遍
  >>>导入包的本质就是执行包下的__inint__.py文件
在导入的过程中,要确保存储路径在同级目录下。如果不在那怎么解决呢?

 1 #Author:ZhangKanghui
 2 
 3 import package#直接运行
 4 
 5 import sys
 6 print(sys.path)         #获取当前文件的存储位置
 7 
 8 import os
 9 print(os.path.abspath(__file__))       #获取当前文件的存储路径
10 print(os.path.dirname(os.path.abspath(__file__)))
11 
12 #添加路径:
13 sys.path.append()       #追加到sys.path的最后,如果想放到前面怎么办
14 sys.path.insert()
15 
16 #os、sys模块下面有详解

访问目录

 

4 内置模块详解

(1)time

首先,在python中有这么几种表示时间的方法:

  (1)时间戳

  (2)元组(struct_time)共有九个元素:年,月,日,小时,分钟,秒,一周的第几天,一年的第几天,时区

  (3)格式化的时间字符串

1 >>> import time
2 >>> time.time()
3 1534000340.4254425        #这是从1970年开始计算至今的秒数。
4 #这是命令行操作
5     

时间戳time.time()

1 >>> time.localtime()
2 time.struct_time(tm_year=2018, tm_mon=8, tm_mday=11, tm_hour=23, tm_min=17, tm_sec=19, tm_wday=5, tm_yday=223, tm_isdst=0)

元组 localtime()

1 x =time.localtime()
2 >>> x
3 time.struct_time(tm_year=2018, tm_mon=8, tm_mday=12, tm_hour=0, tm_min=0, tm_sec=43, tm_wday=6, tm_yday=224, tm_isdst=0)
4 >>> time.strftime("%Y-%m-%d %H:%m:%S",x)
5 \'2018-08-12 00:08:43\'

格式化的时间字符串time.strftime()

科普:

>>>UTC(Coordinated Universal Time,世界协调时)即格林威治天文时间,世界标准时间。在中国为UTC+8,
>>>DST(Daylight Saving Time)即夏令时

在补充一点格式:

>>>comomly used format code:

 1 %Y Year with century as a decimal number.
 2 %m Month as a decimal number [01,12].
 3 %d Day of the month as a decimal number [01,31].
 4 %H Hour (24-hour clock) as a decimal number [00,23].
 5 %M Minute as a decimal number [00,59].
 6 %S Second as a decimal number [00,61].
 7 %z Time zone offset from UTC.
 8 %a Locale\'s abbreviated weekday name.
 9 %A Locale\'s full weekday name.
10 %b Locale\'s abbreviated month name.
11 %B Locale\'s full month name.
12 %c Locale\'s appropriate date and time representation.
13 %I Hour (12-hour clock) as a decimal number [01,12].
14 %p Locale\'s equivalent of either AM or PM.

commmonly used format code

 

a  time.localtime()  将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。

b  time.gmtime()     将一个时间戳转换为UTC时区(0时区)的struct_time。

 

>>> time.localtime()
time.struct_time(tm_year=2018, tm_mon=8, tm_mday=15, tm_hour=10, tm_min=3, tm_sec=22, tm_wday=2, tm_yday=227, tm_isdst=0)
>>> time.gmtime()
time.struct_time(tm_year=2018, tm_mon=8, tm_mday=15, tm_hour=2, tm_min=3, tm_sec=30, tm_wday=2, tm_yday=227, tm_isdst=0)
#这也验证了中国时区是UTC+8

二者有什么区别呢?

 

c  time.mktime()  将一个struct_time转化为时间戳 

1 >>> x =time.localtime()
2 >>> x
3 time.struct_time(tm_year=2018, tm_mon=8, tm_mday=15, tm_hour=10, tm_min=7, tm_sec=30, tm_wday=2, tm_yday=227, tm_isdst=0)
4 >>> time.mktime(x)
5 1534298850.0

time.mktime()

d time.strftime(format[,t])    

1 >>>import time
2 >>> x =time.localtime()
3 >>> x
4 time.struct_time(tm_year=2018, tm_mon=8, tm_mday=15, tm_hour=10, tm_min=13, tm_sec=47, tm_wday=2, tm_yday=227, tm_isdst=0)
5 >>> time.strftime("%Y-%m-%d %H:%m:%S",x)
6 \'2018-08-15 10:08:47\'

time.strftime()

e  time.strptime([格式化时间, format])   把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。

1 >>>import time
2 >>>time.strptime(\'2011-05-05 16:37:06\', \'%Y-%m-%d %X\')
3 time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6, tm_wday=3, tm_yday=125, tm_isdst=-1)

time.strptime([格式化时间,format])

f  asctime([t])        把一个表示时间的元组或者struct_time表示为这种形式:\’Sun Jun 20 23:21:05 1993\’。如果没有参数,将会将time.localtime()作为参数传入。

g  ctime([seconds])       把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。

1 >>> time.asctime()
2 \'Sun Aug 12 23:27:28 2018\'
3 >>> time.ctime()
4 \'Sun Aug 12 23:52:40 2018\'
5 #不要忘记导入time模块哟

一起来看看

接下来上图~

 

(2)datetime

a  datetime.datetime.now()    

1 >>> import datetime
2 >>> datetime.datetime.now()
3 datetime.datetime(2018, 8, 12, 23, 54, 0, 324086)

datetime.datetime.now()

b  datetime.date.fromtimestamp(time.time())  时间戳直接转成日期格式

1 >>> datetime.date.fromtimestamp(time.time())
2 datetime.date(2018, 8, 12)

时间戳

1 >>> datetime.datetime.now() + datetime.timedelta(3)
2 datetime.datetime(2018, 8, 15, 23, 55, 31, 676392)

当前时间+3天

1 >>> datetime.datetime.now() + datetime.timedelta(-3)
2 datetime.datetime(2018, 8, 9, 23, 55, 57, 20937)

当前时间-3天

1 >>> datetime.datetime.now() + datetime.timedelta(hours=3)
2 datetime.datetime(2018, 8, 13, 2, 56, 25, 388509)

当前时间+3小时

1 >>> datetime.datetime.now() + datetime.timedelta(minutes=30)
2 datetime.datetime(2018, 8, 13, 0, 26, 53, 300279)

当前时间+30分

(3)random

 1 #random.random()    生成一个0-1的随机浮点数
 2 >>> random.random()
 3 0.6813665412962242
 4 #那么能不能指定范围呢?
 5 #random.uniform(a,b)   
 6 >>> random.uniform(2,5)
 7 3.7103054399886606 
 8 #random.randint(a,b)    用于生成一个指定范围内的整数,包括a,b
 9 >>> random.randint(1,3)
10 3
11 >>> random.randint(1,3)
12 3
13 >>> random.randint(1,3)
14 1
15 #random.randrange(start,stop,step)  从指定范围获得一个随机数,但不包括stop
16 >>> random.randrange(1,3)
17 2
18 >>> random.randrange(1,3)
19 1
20 #random.choice("序列")            从序列中获取一个随机元素
21 >>> random.choice(\'hello\')
22 \'e\'
23 >>> random.choice(\'hello\')
24 \'o\'
25 >>> random.choice(\'hello\')
26 \'o\'
27 >>> random.choice(\'hello\')
28 \'o\'
29 >>> random.choice(\'hello\')
30 \'e\'
31 #random.sample("序列",k)     从序列中获取k个随机元素,必须指定k
32 >>> random.sample(\'hello\',2)
33 [\'l\', \'h\']
34 >>> random.sample(\'hello\',2)
35 [\'h\', \'o\']
36 >>> random.sample(\'hello\',2)
37 [\'h\', \'o\']
38 random.shuffle()                    洗牌
39 >>> l =[1,2,3,4,5,6]
40 >>> import random
41 >>> random.shuffle(l)
42 >>> l
43 [4, 6, 3, 2, 1, 5]

random模块

(2)os模块

os模块是与操作系统交互的一个接口

a  os.getcwd()       获取当前工作目录
b  os.chdir()      改变工作目录

1 os.getcwd()
2 \'C:\\Users\\miraacle\'
3 >>> os.chdir(\'C:\\Users\')
4 >>> os.getcwd()
5 \'C:\\Users\'
6 >>> os.chdir(r"C:\Users\miraacle")     #对比上一条chdir命令有什么区别/
7 >>> os.getcwd()
8 \'C:\\Users\\miraacle\'

如何操作

c  os.curdir()       返回当前目录

d  os.pardir()        返回当前目录的上一级目录

1 >>> os.curdir
2 \'.\'
3 >>> os.pardir
4 \'..\'

看操作

d  os.makedirs(r”C:\a\b\c\d”)     生成多层递归目录
e  os.removesdirs(r”C:\a\b\c\d”)     若目录为空,则删除,并递归到上一级目录,若也为空则删除,以此类推。
f  os.mkdir()             生成单级目录
g  os.rmdir()             删除单级目录
h  os.listdir()

os.listdir(\’.\’)

1 >>> os.listdir(\'.\')
2 [\'.android\', \'.astropy\', \'.conda\', \'.ipython\', \'.matplotlib\', \'.oracle_jre_usage\', \'.Origin\', \'.PyCharm2017.1\', \'.QtWebEngineProcess\',\'3D Objects\', \'Anaconda3\', \'AppData\', \'Application Data\', \'Contacts\', \'Cookies\', \'Desktop\', \'Documents\', \'Downloads\', \'Evernote\', \'Favorites\', \'IntelGraphicsProfiles\', \'Links\', \'Local Settings\', \'LocalStorage\', \'MicrosoftEdgeBackups\', \'Music\', \'My Documents\', \'NetHood\', \'NTUSER.DAT\', \'ntuser.dat.LOG1\', \'ntuser.dat.LOG2\', \'NTUSER.DAT{2fe3e105-6421-11e8-b183-74e6e23ee3d1}.TM.blf\', \'NTUSER.DAT{2fe3e105-6421-11e8-b18374e6e23ee3d1}.TMContainer00000000000000000001.regtrans-ms\', \'NTUSER.DAT{2fe3e105-6421-11e8-b183-74e6e23ee3d1}.TMContainer00000000000000000002.regtrans-ms\', \'ntuser.ini\', \'OneDrive\', \'OneDrive.old\', \'Pictures\', \'PrintHood\', \'PyCharm 2017.1.2\', \'PycharmProjects\',\'Recent\', \'Saved Games\', \'Searches\', \'SendTo\', \'Templates\', \'Videos\', \'WebpageIcons.db\', \'「开始」菜单\', \'微博图片\', \'新建文件夹\']

一堆东西

os.list(\’..\’)

1 >>> os.listdir(\'..\')
2 [\'Administrator\', \'All Users\', \'Default\', \'Default User\', \'Default.migrated\', \'desktop.ini\', \'miraacle\', \'Public\']

这就清楚多了

i  os.remove()             删除一个文件
j  os.rename(\’oldname\’,\’newname\’)

k  os.stat(\’path\’)             详细信息属性

1 >>> os.stat(\'微博图片\')
2 os.stat_result(st_mode=16895, st_ino=5910974511128476, st_dev=43069414, st_nlink=1, st_uid=0, st_gid=0, st_size=0, 
3 st_atime=1481191549, st_mtime=1481191549, st_ctime=1462148410)

详细属性

l  os.sep               输出操作系统特定的路径分隔符

m  os.linesep            输出当前平台使用的行终止符  dd       

n  os.pathsep             输出用于分割文件路径的字符串

o  os.name             输出字符串当前使用的平台

>>> os.sep
\'\\\'
>>> os.linesep
\'\r\n\'
>>> os.pathsep
\';\'
>>> os.name
\'nt\'

操作集锦

p  os.environ             获取系统环境变量

 1 >>> os.environ
 2 environ({\'ACTEL_FOR_ALTIUM_OVERRIDE\': \' \', \'ALLUSERSPROFILE\': \'C:\\ProgramData\', \'ALTERA_FOR_ALTIUM_OVERRIDE\': \' \', \'ALTIUMPATH\': \'C:\\Program Files (x86)\\Altium2004 SP2\\System\', \'APPDATA\': \'C:\\Users\\miraacle\\AppData\\Roaming\', 
 3 \'CM2015DIR\': \'C:\\Program Files (x86)\\Common Files\\Autodesk Shared\\Materials\\\', \'COMMONPROGRAMFILES\': 
 4 \'C:\\Program Files (x86)\\Common Files\', \'COMMONPROGRAMFILES(X86)\': \'C:\\Program Files (x86)\\Common Files\', 
 5 \'COMMONPROGRAMW6432\': \'C:\\Program Files\\Common Files\', \'COMPUTERNAME\': \'MIRACLE\', \'COMSPEC\': \'C:\\WINDOWS\\system32\\cmd.exe\', 
 6 \'DRIVERDATA\': \'C:\\Windows\\System32\\Drivers\\DriverData\', \'FPS_BROWSER_APP_PROFILE_STRING\': \'Internet Explorer\',
 7 \'FPS_BROWSER_USER_PROFILE_STRING\': \'Default\', \'HOMEDRIVE\': \'C:\', \'HOMEPATH\': \'\\Users\\miraacle\', \'LOCALAPPDATA\': 
 8 \'C:\\Users\\miraacle\\AppData\\Local\', \'LOGONSERVER\': \'\\\\MIRACLE\', \'NUMBER_OF_PROCESSORS\': \'4\', \'ONEDRIVE\': 
 9 \'C:\\Users\\miraacle\\OneDrive\', \'OS\': \'Windows_NT\', \'PATH\': \'C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\WIDCOMM\\Bluetooth Software\\;C:\\Program Files\\WIDCOMM\\BluetoothSoftware\\syswow64;;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Program Files (x86)\\Altium2004 SP2\\System;C:\\Users\\miraacle\\AppData\\Local\\Programs\\Python\\Python36-32\\Scripts\\;
10 C:\\Users\\miraacle\\AppData\\Local\\Programs\\Python\\Python36-32\\;C:\\Users\\miraacle\\Anaconda3;
11 C:\\Users\\miraacle\\Anaconda3\\Scripts;C:\\Users\\miraacle\\Anaconda3\\Library\\bin;
12     C:\\Users\\miraacle\\AppData\\Local\\Microsoft\\WindowsApps;\', \'PATHEXT\': \'.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC\', 
13     \'PROCESSOR_ARCHITECTURE\': \'x86\', \'PROCESSOR_ARCHITEW6432\': \'AMD64\', \'PROCESSOR_IDENTIFIER\': \'Intel64 Family 6 Model 61 Stepping 4, 
14     GenuineIntel\', \'PROCESSOR_LEVEL\': \'6\', \'PROCESSOR_REVISION\': \'3d04\', \'PROGRAMDATA\': \'C:\\ProgramData\', \'PROGRAMFILES\': 
15     \'C:\\Program Files (x86)\', \'PROGRAMFILES(X86)\': \'C:\\Program Files (x86)\', \'PROGRAMW6432\': \'C:\\Program Files\', \'PROMPT\': 
16     \'$P$G\', \'PSMODULEPATH\': \'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules\',
17     \'PUBLIC\': \'C:\\Users\\Public\', \'SESSIONNAME\': \'Console\', \'SYNAPROGDIR\': \'Synaptics\\SynTP\', \'SYSTEMDRIVE\': \'C:\', \'SYSTEMROOT\': 
18     \'C:\\WINDOWS\', \'TEMP\': \'C:\\Users\\miraacle\\AppData\\Local\\Temp\', \'TMP\': \'C:\\Users\\miraacle\\AppData\\Local\\Temp\', 
19     \'USERDOMAIN\': \'MIRACLE\', \'USERDOMAIN_ROAMINGPROFILE\': \'MIRACLE\', \'USERNAME\': \'miraacle\', \'USERPROFILE\': \'C:\\Users\\miraacle\', 
20     \'WINDIR\': \'C:\\WINDOWS\'})

可怕的环境变量

q  os.system()

 1 >>> os.system(\'dir\')
 2      驱动器 C 中的卷是 我的磁盘
 3      卷的序列号是 0291-2FE6
 4 
 5     C:\Users\miraacle 的目录
 6 
 7     2018/08/10  00:17    <DIR>          .
 8     2018/08/10  00:17    <DIR>          ..
 9     2015/05/10  21:32    <DIR>          .android
10     2018/07/04  22:40    <DIR>          .astropy
11     2018/07/23  01:27    <DIR>          .conda
12     2018/07/04  22:38    <DIR>          .ipython
13     2018/07/04  22:51    <DIR>          .matplotlib
14     2016/11/23  22:45    <DIR>          .oracle_jre_usage
15     2017/01/17  22:43    <DIR>          .Origin
16     2018/06/17  00:53    <DIR>          .PyCharm2017.1
17     2017/01/17  22:43    <DIR>          .QtWebEngineProcess
18     2018/07/18  17:47    <DIR>          3D Objects
19     2018/08/13  10:23    <DIR>          Anaconda3
20     2018/07/18  17:47    <DIR>          Contacts
21     2018/08/13  14:04    <DIR>          Desktop
22     2018/07/18  17:47    <DIR>          Documents
23     2018/08/12  23:49    <DIR>          Downloads
24     2016/10/21  18:36    <DIR>          Evernote
25     2018/07/18  17:47    <DIR>          Favorites
26     2018/07/18  17:47    <DIR>          Links
27     2017/01/15  16:13    <DIR>          LocalStorage
28     2018/07/18  17:47    <DIR>          Music
29     2018/04/05  01:08    <DIR>          OneDrive
30     2015/05/21  18:28    <DIR>          OneDrive.old
31     2018/07/18  17:47    <DIR>          Pictures
32     2018/06/17  00:50    <DIR>          PyCharm 2017.1.2
33     2018/07/04  23:11    <DIR>          PycharmProjects
34     2018/07/18  17:47    <DIR>          Saved Games
35     2018/07/18  17:47    <DIR>          Searches
36     2018/07/18  17:47    <DIR>          Videos
37     2017/06/14  00:26            22,528 WebpageIcons.db
38     2016/12/08  18:05    <DIR>          微博图片
39     2017/05/04  09:33    <DIR>          新建文件夹
40                    1 个文件         22,528 字节
41                   32 个目录 43,556,442,112 可用字节
42     0

看看系统

 1 >>> os.system(\'ipconfig/all\')
 2 
 3     Windows IP 配置
 4 
 5        主机名  . . . . . . . . . . . . . : miracle
 6        主 DNS 后缀 . . . . . . . . . . . :
 7        节点类型  . . . . . . . . . . . . : 混合
 8        IP 路由已启用 . . . . . . . . . . : 否
 9        WINS 代理已启用 . . . . . . . . . : 否
10 
11     以太网适配器 以太网:
12 
13        媒体状态  . . . . . . . . . . . . : 媒体已断开连接
14        连接特定的 DNS 后缀 . . . . . . . :
15        描述. . . . . . . . . . . . . . . : Realtek PCIe FE Family Controller
16        物理地址. . . . . . . . . . . . . : 74-E6-E2-3E-E3-D1
17        DHCP 已启用 . . . . . . . . . . . : 是
18        自动配置已启用. . . . . . . . . . : 是
19 
20     无线局域网适配器 本地连接* 2:
21 
22        媒体状态  . . . . . . . . . . . . : 媒体已断开连接
23        连接特定的 DNS 后缀 . . . . . . . :
24        描述. . . . . . . . . . . . . . . : Microsoft Wi-Fi Direct Virtual Adapter
25        物理地址. . . . . . . . . . . . . : 2E-33-7A-FC-F0-B5
26        DHCP 已启用 . . . . . . . . . . . : 是
27        自动配置已启用. . . . . . . . . . : 是
28 
29     无线局域网适配器 本地连接* 4:
30 
31        媒体状态  . . . . . . . . . . . . : 媒体已断开连接
32        连接特定的 DNS 后缀 . . . . . . . :
33        描述. . . . . . . . . . . . . . . : Microsoft Wi-Fi Direct Virtual Adapter #3
34        物理地址. . . . . . . . . . . . . : 2E-33-7A-FC-F8-B5
35        DHCP 已启用 . . . . . . . . . . . : 是
36        自动配置已启用. . . . . . . . . . : 是
37 
38     无线局域网适配器 WLAN:
39 
40        连接特定的 DNS 后缀 . . . . . . . :
41        描述. . . . . . . . . . . . . . . : Dell Wireless 1704 802.11b/g/n (2.4GHz)
42        物理地址. . . . . . . . . . . . . : 2C-33-7A-FC-F0-B5
43        DHCP 已启用 . . . . . . . . . . . : 是
44        自动配置已启用. . . . . . . . . . : 是
45        IPv6 地址 . . . . . . . . . . . . : 2001:250:20a:1900:1c19:8fdc:c570:89f6(首选)
46        临时 IPv6 地址. . . . . . . . . . : 2001:250:20a:1900:5d56:4217:aa5a:e812(首选)
47        本地链接 IPv6 地址. . . . . . . . : fe80::1c19:8fdc:c570:89f6%3(首选)
48        IPv4 地址 . . . . . . . . . . . . : 10.20.72.135(首选)
49        子网掩码  . . . . . . . . . . . . : 255.255.224.0
50        获得租约的时间  . . . . . . . . . : 2018年8月13日 9:30:01
51        租约过期的时间  . . . . . . . . . : 2018年8月13日 14:58:54
52        默认网关. . . . . . . . . . . . . : fe80::276:86ff:febe:7a41%3
53                                            10.20.95.254
54        DHCP 服务器 . . . . . . . . . . . : 10.100.100.100
55        DHCPv6 IAID . . . . . . . . . . . : 36451194
56        DHCPv6 客户端 DUID  . . . . . . . : 00-01-00-01-1E-59-AF-DE-74-E6-E2-3E-E3-D1
57        DNS 服务器  . . . . . . . . . . . : 202.112.209.122
58                                            202.112.209.123
59        TCPIP 上的 NetBIOS  . . . . . . . : 已启用
60     0

看看ip配置

r  os.path.xxx

 1 os.path.abspath()        获取某一文件的绝对路径
 2 os.path.split(path)        分割路径
 3 os.path.diranme(path)    返回path的目录,其实就是os.path.split()的第一个元素
 4 os.path.basename(path)    返回path的最后一个文件名
 5 os.path.exists(path)        判断路径是否存在
 6 os.path.isabs(path)        判断是否为绝对路径
 7 os.path.isfile(path)        判断是否为文件    
 8 os.path.isdir(path)        判断是否为目录
 9 os.path.join()            将说个路径组合返回
10 os.path.getatime(path)    返回path所指向的文件或目录的最后存储时间
11 so.path.getmtime(path)    返回path所指向的文件或目录的最后修改时间

关于os.path.xxx

终于完了~

(5)sys模块

 a  sys.version       获取python解释器的版本信息

b  sys.platform       获取操作系统平台名称

c  sys.argv         命令行参数list,第一个元素是程序本身路径    

d  sys.path          返回模块的搜索路径,初始化时使用python环境变量的值

e  sys.exit(n)        退出程序,正常退出时exit(0)

>>> sys.version
\'3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)]\'
>>> sys.platform
\'win32\'
>>>C:\Users\miraacle\PycharmProjects\s\day5>module_sys.py 1 2 3 4 5
[\'C:\\Users\\miraacle\\PycharmProjects\\s\\day5\\module_sys.py\', \'1\', \'2\', \'3\', \'4\', \'5\']

sys模块操作

 (6)json&pickle模块

json把字符串、列表、字典等各语言通用的数据类型写进文件里。便于各平台和语言之前进行数据交互。

pickle,用于python特有的类型和python的数据类型间进行转换。

 1 #Author:ZhangKanghui
 2 import json
 3 
 4 info ={
 5     \'name\':\'Kanghui\',
 6     \'age\':23
 7 }
 8 #强行转成字符串,不推荐使用。因为反序列化不好办。
 9 \'\'\'
10 f =open(\'文本.txt\',\'w\')
11 #f.write(info)               #TypeError: write() argument must be str, not dict
12 f.write(str(info))
13 f.close()
14 \'\'\'
15 #推荐使用json.dumps或者dump
16 f =open(\'文本.txt\',\'w\')
17 f.write( json.dumps(info) )    #等价于json.dump(info,f)
18 f.close()

json序列化

 1 #Author:ZhangKanghui
 2 
 3 import json
 4 #json只能处理简单的数据类型,例如字典,列表字符串。json在所有语言之间都一样。因为不同语言进行数据交互,能够使用不同语言。
 5 #xml用于在不同语言之间进行数据交互,在不断地被json取代,主流的在不同平台和语言之间数据交互。因为跨语言,所以不能处理复杂的
 6 
 7 f =open(\'文本.txt\',\'r\')
 8 #f.write(info)       TypeError: write() argument must be str, not dict
 9 # data =f.read()
10 # f.close()
11 # print(data)
12 #print(data["age"])       此时TypeError: string indices must be integers因为是字符串,现在需要变回字典
13 #那怎么办呢?
14 \'\'\'
15 data =eval( f.read() )
16 f.close()
17 print(data["age"])
18 \'\'\'
19 #不用eval呢?eval不是一个通用的
20 data =json.loads(f.read())
21 print(data["age"])

json反序列化

 1 #Author:ZhangKanghui
 2 import pickle
 3 date ={"k1":123,"k2":\'hello\'}
 4 #pickle.dumps   将数据通过特殊形式转换为只有python语言认识的字符串
 5 p_str =pickle.dumps(data)
 6 print(p_str)
 7 
 8 #pickle.dump  将数据通过特殊形式转换为只有python语言认识的字符串,并写入文件
 9 with open(\'pickle序列化文本.txt\',\'w\') as f:
10     pickle.dump(date,f)

pickle序列化

 1 #Author:ZhangKanghui
 2 #pickle和json的用法几乎完全一样
 3 import pickle
 4 
 5 def sayhi(name):
 6     print("hello",name)
 7 info ={
 8     \'name\':\'Kanghui\',
 9     \'age\':23,
10     \'func\':sayhi
11 }
12 f =open(\'文本.txt\',\'wb\')
13 f.write( pickle.dump(info) )
14 f.close()

可以dump不一样可以load

 

pickle的用于与json完全一样。

(7)shelve模块

shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。

 1 #Author:ZhangKanghui
 2 
 3 import shelve
 4 import datetime
 5 d =shelve.open("text.txt",\'w\')          #打开一个文件
 6 \'\'\'
 7 info ={"age":23,"job":\'std\'}
 8 name =["a","b"]
 9 d[\'name\']=name              #持久化列表
10 d[\'info\']=info              #持久化字典
11 d["date"]=datetime.datetime.now()
12 d.close()
13 \'\'\'
14 print(d.get("name"))
15 print(d.get("info"))
16 print(d.get("date"))

shelve模块

运行的结果会生成三个文件:text.txt.bak、text.txt.dir,text.txt.dat。貌似很好用的样子~

(8)xml模块

xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单。

xml的格式如下,就是通过<>节点来区别数据结构的:

 1 <?xml version="1.0"?>
 2 <data>
 3     <country name="Liechtenstein">
 4         <rank updated="yes">2</rank>
 5         <year>2008</year>
 6         <gdppc>141100</gdppc>
 7         <neighbor name="Austria" direction="E"/>
 8         <neighbor name="Switzerland" direction="W"/>
 9     </country>
10     <country name="Singapore">
11         <rank updated="yes">5</rank>
12         <year>2011</year>
13         <gdppc>59900</gdppc>
14         <neighbor name="Malaysia" direction="N"/>
15     </country>
16     <country name="Panama">
17         <rank updated="yes">69</rank>
18         <year>2011</year>
19         <gdppc>13600</gdppc>
20         <neighbor name="Costa Rica" direction="W"/>
21         <neighbor name="Colombia" direction="E"/>
22     </country>
23 </data>

xml格式

xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:

 1 import xml.etree.ElementTree as ET
 2  
 3 tree = ET.parse("xmltest.xml")
 4 root = tree.getroot()
 5 print(root.tag)
 6  
 7 #遍历xml文档
 8 for child in root:
 9     print(child.tag, child.attrib)
10     for i in child:
11         print(i.tag,i.text)

遍历xml文档

1 import xml.etree.ElementTree as ET
2  
3 tree = ET.parse("xmltest.xml")
4 root = tree.getroot()
5 print(root.tag)
6 #只遍历year 节点
7 for node in root.iter(\'year\'):
8     print(node.tag,node.text)

只遍历节点

还可以修改和删除xml文档:

 1 import xml.etree.ElementTree as ET
 2  
 3 tree = ET.parse("xmltest.xml")
 4 root = tree.getroot()
 5  
 6 #修改
 7 for node in root.iter(\'year\'):
 8     new_year = int(node.text) + 1
 9     node.text = str(new_year)
10     node.set("updated","yes")
11  
12 tree.write("xmltest.xml")
13  
14  
15 #删除node
16 for country in root.findall(\'country\'):
17    rank = int(country.find(\'rank\').text)
18    if rank > 50:
19      root.remove(country)
20  
21 tree.write(\'output.xml\')

xml修改和删除

还可以自行创建xml文档

 1 import xml.etree.ElementTree as ET
 2  
 3  
 4 new_xml = ET.Element("namelist")
 5 name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
 6 age = ET.SubElement(name,"age",attrib={"checked":"no"})
 7 sex = ET.SubElement(name,"sex")
 8 sex.text = \'33\'
 9 name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
10 age = ET.SubElement(name2,"age")
11 age.text = \'19\'
12  
13 et = ET.ElementTree(new_xml) #生成文档对象
14 et.write("test.xml", encoding="utf-8",xml_declaration=True)
15  
16 ET.dump(new_xml) #打印生成的格式

xml文档创建

 

(9)shutil模块

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

 

 1 #Author:ZhangKanghui
 2 #将一个文件拷贝到另一个文件中
 3 import shutil
 4 shutil.copyfileobj(open(\'old xml\',\'r\'),open(\'new xml\',\'w\'))
 5 
 6 #拷贝文件和权限
 7 shutil.copy(\'f1.log\',\'f2.log\')          #目标文件无需存在
 8 
 9 #shutil.copy2(src, dst)拷贝文件和状态信息
10 shutil.copy2(\'f1.log\', \'f2.log\')
11 
12 #仅拷贝权限。内容、组、用户均不变。
13 shutil.copymode(\'f1.log\',\'f2.log\')      #目标文件必须存在
14 
15 #仅拷贝文件的状态信息,包括:mode bits, atime, mtime, flags
16 shutil.copystat(\'f1.log\', \'f2.log\')     #目标文件必须存在
17 
18 #shutil.ignore_patterns(*patterns)
19 #shutil.copytree(src, dst, symlinks=False, ignore=None)
20 #递归的去拷贝文件夹
21 shutil.copytree(\'folder1\', \'folder2\',ignore=shutil.ignore_patterns(\'*.pyc\', \'tmp*\'))
22 # 目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除
23 
24 #shutil.rmtree(path[, ignore_errors[, onerror]])递归的去删除文件
25 shutil.rmtree(\'folder1\')
26 
27 #shutil.move(src, dst)递归的去移动文件,它类似mv命令,其实就是重命名。
28 shutil.move(\'folder1\', \'folder3\')

shutil乱七八糟的操作

 

shutil.make_archive(base_name, format,…)

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

  • base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    如 data_bak                       =>保存至当前路径
    如:/tmp/data_bak =>保存至/tmp/
  • format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
  • root_dir: 要压缩的文件夹路径(默认当前目录)
  • owner: 用户,默认当前用户
  • group: 组,默认当前组
  • logger: 用于记录日志,通常是logging.Logger对象
shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:

 1 import zipfile
 2 
 3 # 压缩
 4 z = zipfile.ZipFile(\'laxi.zip\', \'w\')
 5 z.write(\'a.log\')
 6 z.write(\'data.data\')
 7 z.close()
 8 
 9 # 解压
10 z = zipfile.ZipFile(\'laxi.zip\', \'r\')
11 z.extractall(path=\'.\')
12 z.close()

zipfile压缩&解压

 1 import tarfile
 2 
 3 # 压缩
 4 >>> t=tarfile.open(\'/tmp/egon.tar\',\'w\')
 5 >>> t.add(\'/test1/a.py\',arcname=\'a.bak\')
 6 >>> t.add(\'/test1/b.py\',arcname=\'b.bak\')
 7 >>> t.close()
 8 
 9 
10 # 解压
11 >>> t=tarfile.open(\'/tmp/egon.tar\',\'r\')
12 >>> t.extractall(\'/egon\')
13 >>> t.close()

tarfile压缩&解压

 (10)PyYaml模块

Python也可以很容易的处理ymal文档格式,只不过需要安装一个模块,

参考文档     http://pyyaml.org/wiki/PyYAMLDocumentation 

 

(11)cofigpaser模块

用于生成和修改常见配置文档

来看一个好多软件的常见文档格式如下:

 1 [DEFAULT]
 2 ServerAliveInterval = 45
 3 Compression = yes
 4 CompressionLevel = 9
 5 ForwardX11 = yes
 6  
 7 [bitbucket.org]
 8 User = hg
 9  
10 [topsecret.server.com]
11 Port = 50022
12 ForwardX11 = no

我是没见过

如果想用python生成一个这样的文档怎么做呢?

 1 import configparser
 2  
 3 config = configparser.ConfigParser()
 4 config["DEFAULT"] = {\'ServerAliveInterval\': \'45\',
 5                       \'Compression\': \'yes\',
 6                      \'CompressionLevel\': \'9\'}
 7  
 8 config[\'bitbucket.org\'] = {}
 9 config[\'bitbucket.org\'][\'User\'] = \'hg\'
10 config[\'topsecret.server.com\'] = {}
11 topsecret = config[\'topsecret.server.com\']
12 topsecret[\'Host Port\'] = \'50022\'     # mutates the parser
13 topsecret[\'ForwardX11\'] = \'no\'  # same here
14 config[\'DEFAULT\'][\'ForwardX11\'] = \'yes\'
15 with open(\'example.ini\', \'w\') as configfile:
16    config.write(configfile)

python写配置文档

写完了还能再读:

 1 >>> import configparser
 2 >>> config = configparser.ConfigParser()
 3 >>> config.sections()
 4 []
 5 >>> config.read(\'example.ini\')
 6 [\'example.ini\']
 7 >>> config.sections()
 8 [\'bitbucket.org\', \'topsecret.server.com\']
 9 >>> \'bitbucket.org\' in config
10 True
11 >>> \'bytebong.com\' in config
12 False
13 >>> config[\'bitbucket.org\'][\'User\']
14 \'hg\'
15 >>> config[\'DEFAULT\'][\'Compression\']
16 \'yes\'
17 >>> topsecret = config[\'topsecret.server.com\']
18 >>> topsecret[\'ForwardX11\']
19 \'no\'
20 >>> topsecret[\'Port\']
21 \'50022\'
22 >>> for key in config[\'bitbucket.org\']: print(key)
23 ...
24 user
25 compressionlevel
26 serveraliveinterval
27 compression
28 forwardx11
29 >>> config[\'bitbucket.org\'][\'ForwardX11\']
30 \'yes\'

python读取配置文档

 1 [section1]
 2 k1 = v1
 3 k2:v2
 4   
 5 [section2]
 6 k1 = v1
 7  
 8 import ConfigParser
 9   
10 config = ConfigParser.ConfigParser()
11 config.read(\'i.cfg\')
12   
13 # ########## 读 ##########
14 #secs = config.sections()
15 #print secs
16 #options = config.options(\'group2\')
17 #print options
18   
19 #item_list = config.items(\'group2\')
20 #print item_list
21   
22 #val = config.get(\'group1\',\'key\')
23 #val = config.getint(\'group1\',\'key\')
24   
25 # ########## 改写 ##########
26 #sec = config.remove_section(\'group1\')
27 #config.write(open(\'i.cfg\', "w"))
28   
29 #sec = config.has_section(\'wupeiqi\')
30 #sec = config.add_section(\'wupeiqi\')
31 #config.write(open(\'i.cfg\', "w"))
32   
33   
34 #config.set(\'group2\',\'k1\',11111)
35 #config.write(open(\'i.cfg\', "w"))
36   
37 #config.remove_option(\'group2\',\'age\')
38 #config.write(open(\'i.cfg\', "w"))

增删改查

(12)hashlib模块

用于加密相关的操作,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

 1 import hashlib
 2  
 3 m = hashlib.md5()
 4 m.update(b"Hello")
 5 m.update(b"It\'s me")
 6 print(m.digest())
 7 m.update(b"It\'s been a long time since last time we ...")
 8  
 9 print(m.digest()) #2进制格式hash
10 print(len(m.hexdigest())) #16进制格式hash
11 \'\'\'
12 def digest(self, *args, **kwargs): # real signature unknown
13     """ Return the digest value as a string of binary data. """
14     pass
15  
16 def hexdigest(self, *args, **kwargs): # real signature unknown
17     """ Return the digest value as a string of hexadecimal digits. """
18     pass
19  
20 \'\'\'
21 import hashlib
22  
23 # ######## md5 ########
24  
25 hash = hashlib.md5()
26 hash.update(\'admin\')
27 print(hash.hexdigest())
28  
29 # ######## sha1 ########
30  
31 hash = hashlib.sha1()
32 hash.update(\'admin\')
33 print(hash.hexdigest())
34  
35 # ######## sha256 ########
36  
37 hash = hashlib.sha256()
38 hash.update(\'admin\')
39 print(hash.hexdigest())
40  
41  
42 # ######## sha384 ########
43  
44 hash = hashlib.sha384()
45 hash.update(\'admin\')
46 print(hash.hexdigest())
47  
48 # ######## sha512 ########
49  
50 hash = hashlib.sha512()
51 hash.update(\'admin\')
52 print(hash.hexdigest())

hashlib模块,试试吧

python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密

散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;

1 import hmac
2 h = hmac.new(b\'天王盖地虎\', b\'宝塔镇河妖\')
3 print h.hexdigest()

hmac加密

更多关于md5,sha1,sha256等介绍的文章看这里

https://www.tbs-certificates.co.uk/FAQ/en/sha256.html 

 

 (13)re模块

 常用正则表达式符号:五种匹配语法、三种匹配模式

 

 1 \'.\'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
 2 \'^\'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
 3 \'$\'     匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
 4 \'*\'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为[\'abb\', \'ab\', \'a\']
 5 \'+\'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果[\'ab\', \'abb\']
 6 \'?\'     匹配前一个字符1次或0次
 7 \'{m}\'   匹配前一个字符m次
 8 \'{n,m}\' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果\'abb\', \'ab\', \'abb\']
 9 \'|\'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果\'ABC\'
10 \'(...)\' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c

常用的正则表达式1

 

1 \'\A\'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
2 \'\Z\'    匹配字符结尾,同$
3 \'\d\'    匹配数字0-9
4 \'\D\'    匹配非数字
5 \'\w\'    匹配[A-Za-z0-9]
6 \'\W\'    匹配非[A-Za-z0-9]
7 \'s\'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 \'\t\'

常用的正则表达式2

1 \'(?P<name>...)\' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{\'province\': \'3714\', \'city\': \'81\', \'birthday\': \'1993\'}

分组匹配身份证号

五种

1 re.match 从头开始匹配
2 re.search 匹配包含
3 re.findall 把所有匹配到的字符放到以列表中的元素返回
4 re.splitall 以匹配到的字符当做列表分隔符
5 re.sub      匹配字符并替换

匹配语法

三种

1 re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
2 M(MULTILINE): 多行模式,改变\'^\'\'$\'的行为(参见上图)
3 S(DOTALL): 点任意匹配模式,改变\'.\'的行为

匹配模式

下面来看看实例操作:(命令行操作)

 1 >>> re.match("^Kanghui","Kanghui123")
 2 <_sre.SRE_Match object; span=(0, 7), match=\'Kanghui\'>            
 3 #这是匹配到的情况,如果匹配不到呢?是没有反应的。就是none
 4 >>> re.match("^aKanghui","Kanghui123")
 5 >>> re.match("^aKanghui","Kanghui123")
 6 #查看匹配内容
 7 >>> res =re.match("^Kanghui","Kanghui123")
 8 >>> res.group()
 9 \'Kanghui\'
10 #现在这样还没用到正则,那么接下来~我要把后面的数字也匹配进来
11 >>> res =re.match("^Kang\d","Kang123hui123")
12 >>> res.group()
13 \'Kang1\'
14 #现在只有一个数字,多个数字就再加一个+
15 >>> res =re.match("^Kang\d+","Kang123hui123")
16 >>> res.group()
17 \'Kang123\'
18 #接下来开始正式使用正则表示式符号
19 >>> re.match("^.\d+","Kang123hui123")
20 >>> re.match("^.\d+","Kang123hui123")
21 #这样为什么没有反应呢?原因是因为    ^匹配字符开头,    .默认匹配除\n之外的任意一个字符    一个字符之后就是数字所以不行
22 >>> re.match("^.+\d+","Kang123hui123")
23 <_sre.SRE_Match object; span=(0, 13), match=\'Kang123hui123\'>
24 >>> re.match("^.+","Kang123hui123")
25 <_sre.SRE_Match object; span=(0, 13), match=\'Kang123hui123\'>
26 >>> re.match(".+","Kang123hui123")
27 <_sre.SRE_Match object; span=(0, 13), match=\'Kang123hui123\'>
28 >>> re.match(".","Kang123hui123")
29 <_sre.SRE_Match object; span=(0, 1), match=\'K\'>
30 >>> re.match("^K.+","Kang123hui123")
31 <_sre.SRE_Match object; span=(0, 13), match=\'Kang123hui123\'>
32 #如果我只想要数字中间的部分呢?
33 >>> re.search("^h.+i","Kang123hui321")                #^匹配字符开头
34 >>> re.search("h.+i","Kang123hui321")
35 <_sre.SRE_Match object; span=(7, 10), match=\'hui\'>

re模块引入

 1 >>> re.search("^h.+i","Kang123hui321")
 2 >>> re.search("h.+i","Kang123hui321")
 3 <_sre.SRE_Match object; span=(7, 10), match=\'hui\'>
 4 >>> re.search("$","Kang123hui321a")
 5 <_sre.SRE_Match object; span=(14, 14), match=\'\'>
 6 >>> re.search("a$","Kang123hui321a")
 7 <_sre.SRE_Match object; span=(13, 14), match=\'a\'>
 8 >>> re.search(".+a$","Kang123hui321a")
 9 <_sre.SRE_Match object; span=(0, 14), match=\'Kang123hui321a\'>
10 >>> re.search(".+a","Kang123hui321a")
11 <_sre.SRE_Match object; span=(0, 14), match=\'Kang123hui321a\'>
12 这样看起来$貌似没有什么用,因为.+是匹配任意字符。
13 >>> re.search("h[a-z]+","Kang123hui321a")
14 <_sre.SRE_Match object; span=(7, 10), match=\'hui\'>
15 >>> re.search("h[a-z]+i","Kang123hui321i")
16 <_sre.SRE_Match object; span=(7, 10), match=\'hui\'>
17 >>> re.search("h[a-z]+i$","Kang123hui321i")
18 >>> re.search("h[a-zA-Z]+i","Kang123huiKAnghui321i")
19 <_sre.SRE_Match object; span=(7, 17), match=\'huiKAnghui\'>
20 >>> re.search("#.+#","123#hello#")
21 <_sre.SRE_Match object; span=(3, 10), match=\'#hello#\'>
22 >>> re.search("aaa?","alexaaa")
23 <_sre.SRE_Match object; span=(4, 7), match=\'aaa\'>
24 >>> re.search("aaa?","aalexaaa")
25 <_sre.SRE_Match object; span=(0, 2), match=\'aa\'>
26 >>> re.search("aal?","aalexaaa")
27 <_sre.SRE_Match object; span=(0, 3), match=\'aal\'>
28 >>> re.search("aal?","aaexaaa")
29 <_sre.SRE_Match object; span=(0, 2), match=\'aa\'>
30 >>> re.search("[0-9]{3}","a8l26e456x")
31 <_sre.SRE_Match object; span=(6, 9), match=\'456\'>
32 >>> re.search("[0-9]{1,3}","a8l26e456x")
33 <_sre.SRE_Match object; span=(1, 2), match=\'8\'>
34 #如果想要匹配所有的数字呢?用findall试试:

re.search

 1 >>> re.search("[0-9]{1,3}","a8l26e456x")
 2 <_sre.SRE_Match object; span=(1, 2), match=\'8\'>
 3 >>> re.findall("[0-9]{1,2}","a8l26e456x")
 4 [\'8\', \'26\', \'45\', \'6\']
 5 >>> re.findall("[0-9]{1,3}","a8l26e456x")
 6 [\'8\', \'26\', \'456\']
 7 >>> re.search("abc|ABC","ABCabcCDE")
 8 <_sre.SRE_Match object; span=(0, 3), match=\'ABC\'>
 9 >>> re.search("abc|ABC","ABCabcCDE").group()
10 \'ABC\'
11 >>> re.findall("abc|ABC","ABCabcCDE").group()
12 Traceback (most recent call last):
13   File "<stdin>", line 1, in <module>
14 AttributeError: \'list\' object has no attribute \'group\'
15 >>> re.findall("abc|ABC","ABCabcCDE")
16 [\'ABC\', \'abc\']
17 >>> re.search("(abc){2}","subjectabccccabc")
18 >>> re.search("(abc){2}","subjectabccccabcabc")
19 <_sre.SRE_Match object; span=(13, 19), match=\'abcabc\'>
20 >>> re.search("(abc){2}\|","subjectabccccabcabc|")
21 <_sre.SRE_Match object; span=(13, 20), match=\'abcabc|\'>
22 >>> re.search("(abc){2}\|\|=","subjectabccccabcabc||=||=")
23 <_sre.SRE_Match object; span=(13, 22), match=\'abcabc||=\'>
24 >>> re.search("\D+","123#abc")
25 <_sre.SRE_Match object; span=(3, 7), match=\'#abc\'>
26 >>> re.search("\s+","123#abc \r\n       ")
27 <_sre.SRE_Match object; span=(7, 11), match=\' \r\n\t\'>

re.findall

1 >>> re.split("[0-9]","abc12de3f45g6HGD")
2 [\'abc\', \'\', \'de\', \'f\', \'\', \'g\', \'HGD\']
3 >>> re.split("[0-9]+","abc12de3f45g6HGD")
4 [\'abc\', \'de\', \'f\', \'g\', \'HGD\']

re.split

1 >>> re.sub("[0-9]+","|","abc12de3f45g6HGD")
2 \'abc|de|f|g|HGD\'
3 >>> re.sub("[0-9]+","|","abc12de3f45g6HGD",count=2)
4 \'abc|de|f45g6HGD\'

re.sub

最后来个使用性的例子:身份证号码的每个数字都代表着什么你知道吗?

科普:

身份证号码编排规则(18位身份证号码)

公民身份证号码是特征组合码,由17位数字本体码和1位校验码组成。前1、2位数字表示:所在省份的代码;第3、4位数字表示:所在城市的代码;第5、 6位数字表示:所在区县的代码;第7~14位数字表示:出生年、月、日;第15、16位数字表示:所在地的派出所的代码;第17位数字表示性别:奇数表示男性,偶数表示女性;第18位数字是校检码:用来检验身份证号码的正确性,校检码由0~9的数字、及X表示。

1 >>> re.search("(?P<province>[0-9]{2})(?P<city>[0-9]{2})(?P<county>[0-9]{2})(?P<birthday>[0-9]{4})","412727199511282319").groupdict("city")
2 {\'province\': \'41\', \'city\': \'27\', \'county\': \'27\', \'birthday\': \'1995\'}

通过正则取出身份信息

5 练习(开发一个简单的python计算器)

需求:

1实现加减乘除和括号优先级的解析
2用户输入1-2*((60-30)+(40/5)*)等类的公式后,必须自己解析里面的运算符号,运算后得出结果,结果必须与真实计算器一致。

  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 """
  4 该计算器思路:
  5     1、递归寻找表达式中只含有 数字和运算符的表达式,并计算结果
  6     2、由于整数计算会忽略小数,所有的数字都认为是浮点型操作,以此来保留小数
  7 使用技术:
  8     1、正则表达式
  9     2、递归
 10  
 11 执行流程如下:
 12 ******************** 请计算表达式: 1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) ********************
 13 before: [\'1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))\']
 14 -40.0/5=-8.0
 15 after: [\'1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))\']
 16 ========== 上一次计算结束 ==========
 17 before: [\'1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))\']
 18 9-2*5/3+7/3*99/4*2998+10*568/14=173545.880953
 19 after: [\'1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))\']
 20 ========== 上一次计算结束 ==========
 21 before: [\'1-2*((60-30+-8.0*173545.880953)-(-4*3)/(16-3*2))\']
 22 60-30+-8.0*173545.880953=-1388337.04762
 23 after: [\'1-2*(-1388337.04762-(-4*3)/(16-3*2))\']
 24 ========== 上一次计算结束 ==========
 25 before: [\'1-2*(-1388337.04762-(-4*3)/(16-3*2))\']
 26 -4*3=-12.0
 27 after: [\'1-2*(-1388337.04762--12.0/(16-3*2))\']
 28 ========== 上一次计算结束 ==========
 29 before: [\'1-2*(-1388337.04762--12.0/(16-3*2))\']
 30 16-3*2=10.0
 31 after: [\'1-2*(-1388337.04762--12.0/10.0)\']
 32 ========== 上一次计算结束 ==========
 33 before: [\'1-2*(-1388337.04762--12.0/10.0)\']
 34 -1388337.04762--12.0/10.0=-1388335.84762
 35 after: [\'1-2*-1388335.84762\']
 36 ========== 上一次计算结束 ==========
 37 我的计算结果: 2776672.69524
 38 """
 39  
 40  
 41 import re
 42  
 43  
 44 def compute_mul_div(arg):
 45     """ 操作乘除
 46     :param expression:表达式
 47     :return:计算结果
 48     """
 49  
 50     val = arg[0]
 51     mch = re.search(\'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*\', val)
 52     if not mch:
 53         return
 54     content = re.search(\'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*\', val).group()
 55  
 56     if len(content.split(\'*\'))>1:
 57         n1, n2 = content.split(\'*\')
 58         value = float(n1) * float(n2)
 59     else:
 60         n1, n2 = content.split(\'/\')
 61         value = float(n1) / float(n2)
 62  
 63     before, after = re.split(\'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*\', val, 1)
 64     new_str = "%s%s%s" % (before,value,after)
 65     arg[0] = new_str
 66     compute_mul_div(arg)
 67  
 68  
 69 def compute_add_sub(arg):
 70     """ 操作加减
 71     :param expression:表达式
 72     :return:计算结果
 73     """
 74     while True:
 75         if arg[0].__contains__(\'+-\') or arg[0].__contains__("++") or arg[0].__contains__(\'-+\') or arg[0].__contains__("--"):
 76             arg[0] = arg[0].replace(\'+-\',\'-\')
 77             arg[0] = arg[0].replace(\'++\',\'+\')
 78             arg[0] = arg[0].replace(\'-+\',\'-\')
 79             arg[0] = arg[0].replace(\'--\',\'+\')
 80         else:
 81             break
 82  
 83     if arg[0].startswith(\'-\'):
 84         arg[1] += 1
 85         arg[0] = arg[0].replace(\'-\',\'&\')
 86         arg[0] = arg[0].replace(\'+\',\'-\')
 87         arg[0] = arg[0].replace(\'&\',\'+\')
 88         arg[0] = arg[0][1:]
 89     val = arg[0]
 90     mch = re.search(\'\d+\.*\d*[\+\-]{1}\d+\.*\d*\', val)
 91     if not mch:
 92         return
 93     content = re.search(\'\d+\.*\d*[\+\-]{1}\d+\.*\d*\', val).group()
 94     if len(content.split(\'+\'))>1:
 95         n1, n2 = content.split(\'+\')
 96         value = float(n1) + float(n2)
 97     else:
 98         n1, n2 = content.split(\'-\')
 99         value = float(n1) - float(n2)
100  
101     before, after = re.split(\'\d+\.*\d*[\+\-]{1}\d+\.*\d*\', val, 1)
102     new_str = "%s%s%s" % (before,value,after)
103     arg[0] = new_str
104     compute_add_sub(arg)
105  
106  
107 def compute(expression):
108     """ 操作加减乘除
109     :param expression:表达式
110     :return:计算结果
111     """
112     inp = [expression,0]
113  
114     # 处理表达式中的乘除
115     compute_mul_div(inp)
116  
117     # 处理
118     compute_add_sub(inp)
119     if divmod(inp[1],2)[1] == 1:
120         result = float(inp[0])
121         result = result * -1
122     else:
123         result = float(inp[0])
124     return result
125  
126  
127 def exec_bracket(expression):
128     """ 递归处理括号,并计算
129     :param expression: 表达式
130     :return:最终计算结果
131     """
132     # 如果表达式中已经没有括号,则直接调用负责计算的函数,将表达式结果返回,如:2*1-82+444
133     if not re.search(\'\(([\+\-\*\/]*\d+\.*\d*){2,}\)\', expression):
134         final = compute(expression)
135         return final
136     # 获取 第一个 只含有 数字/小数 和 操作符 的括号
137     # 如:
138     #    [\'1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))\']
139     #    找出:(-40.0/5)
140     content = re.search(\'\(([\+\-\*\/]*\d+\.*\d*){2,}\)\', expression).group()
141  
142     # 分割表达式,即:
143     # 将[\'1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))\']
144     # 分割更三部分:[\'1-2*((60-30+(    (-40.0/5)      *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))\']
145     before, nothing, after = re.split(\'\(([\+\-\*\/]*\d+\.*\d*){2,}\)\', expression, 1)
146  
147     print \'before:\',expression
148     content = content[1:len(content)-1]
149  
150     # 计算,提取的表示 (-40.0/5),并活的结果,即:-40.0/5=-8.0
151     ret = compute(content)
152  
153     print \'%s=%s\' %( content, ret)
154  
155     # 将执行结果拼接,[\'1-2*((60-30+(      -8.0     *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))\']
156     expression = "%s%s%s" %(before, ret, after)
157     print \'after:\',expression
158     print "="*10,\'上一次计算结束\',"="*10
159  
160     # 循环继续下次括号处理操作,本次携带者的是已被处理后的表达式,即:
161     # [\'1-2*((60-30+   -8.0  *(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))\']
162  
163     # 如此周而复始的操作,直到表达式中不再含有括号
164     return exec_bracket(expression)
165  
166  
167  
168 # 使用 __name__ 的目的:
169 #   只有执行 python index.py 时,以下代码才执行
170 #   如果其他人导入该模块,以下代码不执行
171 if __name__ == "__main__":
172     #print \'*\'*20,"请计算表达式:", "1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )" ,\'*\'*20
173     #inpp = \'1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) \'
174     inpp = "1-2*-30/-12*(-20+200*-3/-200*-300-100)"
175     #inpp = "1-5*980.0"
176     inpp = re.sub(\'\s*\',\'\',inpp)
177     # 表达式保存在列表中
178     result = exec_bracket(inpp)
179     print result

代码示例

6 小结

做一名程序猿是真的不容易。

最近才觉得好多东西要学啊,亚历山大~~!!!自己就像一张白纸,慢慢填~

坚持~

为什么明明才二十几岁,就感觉一辈子好像就这样了呢?

别忘了看书。

 

 

我是尾巴~

这次推荐一个远程控制电脑的黑科技: 

https://mp.weixin.qq.com/s/SE5QGzwJhA1lKbVuhS9_bg

虽不才,才要坚持~

 

版权声明:本文为zhangkanghui原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/zhangkanghui/p/9480500.html