一、模块介绍
Python Module(模块),就是一个保存了Python代码的文件。模块能定义函数,类和变量。模块里也能包含可执行的代码。
文件名就是模块名加上后缀.py,在模块内部,模块名存储在全局变量__name__中,是一个string,可以直接在module中通过__name__引用到module name。
模块分为三种:
-
自定义模块
-
内置标准模块(又称标准库)
-
开源模块
导入模块:
-
import: 使客户端(导入者)以一个整体获取一个模块。
-
from:容许客户端从一个模块文件中获取特定的变量名。
-
reload:在不中止Python程序的情况下,提供了一个重新载入模块文件代码的方法。
语法: import module from module.xx.xx import xx from module.xx.xx import xx as rename from module.xx.xx import * #一般不推荐使用 示例: 推荐方法一: import cal #当前目录直接调用模块 from my_module import cal #二层目录调用模块 from web1,web2,web3 import cal #多层目录调用模块 推荐方法二: from web1,web2,web3.cal import add 注意:不支持的调用方式 from web1.web2 import web3 #执行__init__文件,唯一不支持的调用方式 print(web3.cal.add(2,6))
模块路径
import sys import os pre_path=os.path.abspath('.../') sys.path.append(pre_path) #添加路径,添加环境变量临时生效
for i in sys.path: #获取路径,
print(i)
注意:
环境变量:永久生效方法:我的电脑--->系统属性--->环境变量--->Path路径中添加,以";" 分割。
二、包(package)的概念
我们先设想一下,如果不同的人编写的模块名相同怎么办?为了避免冲突,Python又引进了按目录
来组织模块的方法,称为包(package)。
假设,如下图,我的两个time_file.py模块名字重名了,但是这两个模块的功能都不相同,如果这两个模块都在同一级目录中,那么我在其他地方要调用这个time_file.py模块,那么这个时候就会发生冲突,
在这里我们就可以通过包来组织模块,避免冲突。
方法是:选择一个顶层包名,引入包以后,只要顶层的包名不与别人冲突,那这个包里面的模块都不会与别人冲突了。
请注意:每个包目录下来都会有一个__init__.py的文件,这个文件必须是存在的,否则,Python就不把这个目录当成普通目录,而不是一个包,__init__.py可以是空文件,
也可以有python代码,__init__.py本身就 是一个文件,它的模块命就是对应的包名,它一般做接口文件。
三、time模块
时间相关的操作,时间有三种表示方式:
时间戳
1970
年
1
月
1
日之后的秒,即:time.time()
格式化的字符串
2016
-
12
-
12
10
:
10
, 即:time.strftime(
'%Y-%m-%d'
)
结构化时间 元组
即:time.struct_time元组共有
9
个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
即:time.localtime()
import time print(time.time()) #当前时间的时间戳
#1528284151.432538
2.将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
time.localtime([secs])
print(time.localtime())
print(time.localtime(1528284151.432538)) >>>>
time.struct_time(tm_year=2018, tm_mon=6, tm_mday=6, tm_hour=19, tm_min=22, tm_sec=31, tm_wday=2, tm_yday=157, tm_isdst=0)
time.struct_time(tm_year=2018, tm_mon=6, tm_mday=6, tm_hour=19, tm_min=22, tm_sec=31, tm_wday=2, tm_yday=157, tm_isdst=0)
3.gmtime([secs]) 和localtime()方法类似,
gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time
print(time.gmtime()) >>>>>> time.struct_time(tm_year=2018, tm_mon=6, tm_mday=6, tm_hour=11, tm_min=28, tm_sec=2, tm_wday=2, tm_yday=157, tm_isdst=0)
4.mktime(t) : 将一个struct_time转化为时间戳。
print(time.mktime(time.localtime())) >>>> 1528284613.0
5.asctime([t]) : 把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。
参数为空时,默认为当前时间
print(time.asctime(time.localtime())) print(time.asctime()) >>>> Wed Jun 6 19:33:52 2018 Wed Jun 6 19:33:52 2018
6.ctime([secs]) : 把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为
None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
print(time.ctime()) >>>>> Wed Jun 6 19:38:34 2018
7. strftime(format[, t]) : 把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。
如果t未指定,将传入time.localtime()。如果元组中任何一个元素越界,ValueError的错误将会被抛出。
print(time.strftime("%Y-%m-%d %X", time.localtime())) >>>> 2018-06-06 19:41:51
8 time.strptime(string[, format])
把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。
在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。
print(time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X')) >>>>> 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)
9.sleep(secs) 线程推迟指定的时间运行,单位为秒。
10.这个需要注意,在不同的系统上含义不同。在UNIX系统上,它返回的是“进程时间”,它是用秒表示的浮点数(时间戳)。
而在WINDOWS中,第一次调用,返回的是进程运行的实际时间。
而第二次之后的调用是自第一次调用以后到现在的运行时间,即两次时间差。
四、random 模块 (随机数)
1.random() 用于生成一个0到1的随机符点数: 0 <= n < 1.0
print(random.random()) >>>>> 0.47674138932530974
2.randint(x,y) 用于生成一个指定范围内的整数
print(random.randint(1,2)) >>>> 2
3.randrange()从指定范围内,按指定基数递增的集合中获取一个随机数
print(random.randrange(1,10)) >>>> 8
4.uniform() 用于生成一个指定范围内的随机符点数
print(random.uniform(1, 10)) >>>> 5.244662335538338
5.choice() 从序列中随机生成一个随机元素
print(random.choice('nice')) >>>> e
6.shuffle(list) 用于将一个列表中的元素打乱
li = ['nick','jenny','car',]
random.shuffle(li)
print(li)
>>>>>
['nick', 'car', 'jenny']
7.sample()从指定序列中随机获取指定长度的片断
li = ['nick','jenny','car',]
print(random.sample(li,2)) #从li中随机获取2个元素,作为一个片断返回
>>>> ['jenny', 'nick']
验证码实例:
五、os模块
os模块是与操作系统交互的一个接口
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.curdir 返回当前目录: ('.') os.pardir 获取当前目录的父目录字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" os.linesep 输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n" os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' os.system("bash command") 运行shell命令,直接显示 os.environ 获取系统环境变量 os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.path.isabs(path) 如果path是绝对路径,返回True os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
1.getcwd 获取当前工作路径
chdir('...') 改变当前脚本工作路径
import os print(os.getcwd()) os.chdir('F:\python') print(os.getcwd())
执行结果
F:\复习
F:\python
2.递归创建空目录
os.makedirs('dirnamel/dirname2') #创建两层
执行结果
3.removedirs 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.removedirs('dirnamel/dirname2')
4、 listdir 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
print(os.listdir()) >>>>> ['.idea', 'a', 'dingxi', 'dingxi2', 'dingxi3', 'Lry', 'module', 'rizhi', 'test', 'test.py', 'venv', 'yesterday2', 'yesterday3', '__pycache__', '元组和字典.py', '内置函数.py', '函数', '函数式编程.py', '列表.py', '字符串.py', '文件处理.py', '模块.py', '装饰器.py', '迭代器和生成器.py', '集合.py']
5. stat 获取文件/目录信息
stat 结构:
- st_mode: inode 保护模式
- st_ino: inode节点号。
- st_dev: inode驻留的设备。
- st_nlink: inode 的链接数。
- st_uid: 所有者的用户ID。
- st_gid: 所有者的组ID。
- st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
- st_atime: 上次访问的时间。
- st_mtime: 最后一次修改的时间。
- st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。
print(os.stat("模块.py"))
>>>>>
['.idea', 'a', 'dingxi', 'dingxi2', 'dingxi3', 'Lry', 'module', 'rizhi', 'test', 'test.py', 'venv', 'yesterday2', 'yesterday3', '__pycache__', '元组和字典.py', '内置函数.py', '函数', '函数式编程.py', '列表.py', '字符串.py', '文件处理.py', '模块.py', '装饰器.py', '迭代器和生成器.py', '集合.py']
os.stat_result(st_mode=33206, st_ino=10133099161584003, st_dev=2259195232, st_nlink=1, st_uid=0, st_gid=0, st_size=1164, st_atime=1528373189, st_mtime=1528373189, st_ctime=1528283987)
6.os.system(("dir")) 显示目录和文件
print(os.system(('dir'))) >>>>> ������ F �еľ��� ������ ������к��� 86A8-9560 F:\��ϰ ��Ŀ¼ 2018/06/07 20:08 <DIR> . 2018/06/07 20:08 <DIR> .. 2018/06/07 20:06 <DIR> .idea 2018/06/06 03:36 64 a 2018/06/06 02:08 925 dingxi 2018/06/06 02:15 922 dingxi2 2018/06/06 02:30 0 dingxi3 2018/06/05 22:59 2,694 Lry 2018/06/06 18:45 <DIR> module 2018/06/06 02:56 216 rizhi 2018/06/06 18:45 <DIR> test 2018/06/03 11:34 30 test.py 2018/06/06 18:43 <DIR> venv 2018/06/05 23:20 13 yesterday2 2018/06/05 23:16 216 yesterday3 2018/06/03 11:34 <DIR> __pycache__ 2018/06/01 13:47 3,288 Ԫ����ֵ�.py 2018/06/03 11:34 4,135 ���ú���.py 2018/06/01 16:03 1,373 ���� 2018/06/01 17:12 1,942 ����ʽ���.py 2018/05/31 14:46 1,885 �б�.py 2018/06/01 13:01 4,105 �ַ���.py 2018/06/06 03:36 6,206 �ļ�����.py 2018/06/07 20:08 1,193 ģ��.py 2018/06/06 15:36 4,069 װ����.py 2018/06/03 20:46 4,099 ��������������.py 2018/06/01 14:58 1,216 ����.py 20 ���ļ� 38,591 �ֽ� 7 ��Ŀ¼ 104,774,754,304 �����ֽ� 0
7. os.path.split 将文件分割成目录和文件名
print(os.path.split(r'F:\复习\模块.py')) >>>> ('F:\\复习', '模块.py')
8.os.path.dirname 返回path的目录,加了r转义
print(os.path.dirname(r'F:\复习\模块.py')) #返回path的目录。其实就是os.path.split(path)的第一个元素
>>>> F:\复习
9.文件路径的综合使用
#获取当前路径的文件名 print(__file__) >>>> F:/复习/模块.py #返回上一层目录 print(os.path.dirname(__file__)) >>> F:/复习 #返回他的绝对路径 print(os.path.abspath(__file__)) >>>> F:\复习\模块.py #将path分割成目录和文件名 print(os.path.split(os.path.abspath(__file__))) >>>> ('F:\\复习', '模块.py') ##返回当前文件的上一层目录 print(os.path.dirname(os.path.abspath(__file__))) >>>> F:\复习 #返回上二层的目录 print(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) >>>> F:\
10.ps.path.hasename 返回path最后的文件名
print(os.path.basename(r'F:\复习\模块.py')) >>>> 模块.py
11.os.path.join 路径拼接
import os a="F:\python\模块" b="pickle_s1.py" print(os.path.join(a,b))# 路径拼接 >>>> F:\python\模块\pickle_s1.py
os.path.join 路径和文件名拼接
print(os.path.join("d:\\")) print(os.path.join("d:\\","www","baidu","test.py")) >>>> print(os.path.join("d:\\")) print(os.path.join("d:\\","www","baidu","test.py"))
12.\test\bb\123.txt os.path.join拼接出这个路径
print(os.path.join(os.path.dirname(os.path.abspath(__file__)),"bb","123.txt")) >>>> F:\复习\bb\123.txt
六、sys模块
1.sys.argv 命令行参数List,第一个元素是程序本身路径
2.sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
import sys print(sys.path) >>>>> ['F:\\复习', 'F:\\复习', 'F:\\复习\\venv\\Scripts\\python36.zip', 'D:\\Python\\Python36-32\\DLLs', 'D:\\Python\\Python36-32\\lib', 'D:\\Python\\Python36-32', 'F:\\复习\\venv', 'F:\\复习\\venv\\lib\\site-packages', 'F:\\复习\\venv\\lib\\site-packages\\setuptools-39.0.1-py3.6.egg', 'F:\\复习\\venv\\lib\\site-packages\\pip-9.0.3-py3.6.egg', 'D:\\JetBrains\\PyCharm 2018.1.4\\helpers\\pycharm_matplotlib_backend']
import sys for i in sys.path: print(i) >>>>> F:\复习 F:\复习 F:\复习\venv\Scripts\python36.zip D:\Python\Python36-32\DLLs D:\Python\Python36-32\lib D:\Python\Python36-32 F:\复习\venv F:\复习\venv\lib\site-packages F:\复习\venv\lib\site-packages\setuptools-39.0.1-py3.6.egg F:\复习\venv\lib\site-packages\pip-9.0.3-py3.6.egg D:\JetBrains\PyCharm 2018.1.4\helpers\pycharm_matplotlib_backend
3.sys.version 获取Python解释程序的版本信息
print(sys.version) >>>> 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)]
4.sys.exit(n) 退出程序,正常退出时exit(0)
5.sys.maxint 最大的Int值
6.sys.platform 返回操作系统平台名称
7.进度条的实现
for i in range(10): sys.stdout.write('*') time.sleep(1) sys.stdout.flush()
七、json & pickle(* * * *)
用于序列化的两个模块
- json,用于字符串 和 python数据类型间进行转换
- pickle,用于python特有的类型 和 python的数据类型间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
dump()函数接受一个文件句柄和一个数据对象作为参数,把数据对象以特定的格式保存 到给定的文件中。当我们使用load()函数从文件中取出已保存的对象时,pickle知道如何恢复这些对象到它们本来的格式。
dumps()函数执行和dump() 函数相同的序列化。取代接受流对象并将序列化后的数据保存到磁盘文件,这个函数简单的返回序列化的数据。
loads()函数执行和load() 函数一样的反序列化。取代接受一个流对象并去文件读取序列化后的数据,它接受包含序列化后的数据的str对象, 直接返回的对象。
json
1.把一个字典,写入到文件中
dic='{''name'':''Alex'',''age'':19}' #一定要注意写成字符串形式 f=open('hello','w') f.write(dic)
2.使用json方法把字典转换成json形式的字符串写入文件中
推荐使用:
import json dic={'name':'Alex','age':19} dic=json.dumps(dic) f=open('hello','w')
f.write(dic)
import json dic={'name':'Alex','age':19} f = open('hello', 'a') dic=json.dump(dic,f)
3.json序列化
把文件中json类型的字符串读取出来转换成字典
f = open('hello','r') f = json.loads(f.read()) print(f) print(type(f)) >>>>> {'name': 'Alex', 'age': 19} <class 'dict'>
#不推荐使用
f=open('hello','r') f=json.load(f) print(f) print(type(f))
注意的知识点:
1.无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
import json # dic="{'1':'1'}" #json不认单引号 # dit=str({"1":"1"}) # dic=str(dit) dit='{"1":"1"}' print(json.loads(dit)) >>>> {'1': '1'}
2.先创建一个json_test文件,写入内容
{"name":"ALEX"} #只要符合json规范就可以把值取出来。 另一种示例:{'name':"alvin"} #如果是'name' 的值是单引号就会报错。
with open('json_test.py','r') as f: data=f.read() data=json.loads(data) print(data['name']) >>>>> ALEX
json的dumps,loads,dump,load功能总结:
json.dumps(x) 把python的(x)原对象转换成json字符串的对象,主要用来写入文件。
json.loads(f) 把json字符串(f)对象转换成python原对象,主要用来读取文件和json字符串
json.dump(x,f) 把python的(x)原对象,f是文件对象,写入到f文件里面,主要用来写入文件的
json.load(file) 把json字符串的文件对象,转换成python的原对象,只是读文件
pickle序列化
1.pickle转换后的结果是bytes(字节)
import pickle dic={'name':'alvin','age':23,'sex':'male'} print(type(dic)) j=pickle.dumps(dic) print(type(j)) >>>>> <class 'dict'> <class 'bytes'>
2.
dic={'name':'alvin','age':23,'sex':'male'} j=pickle.dumps(dic) f=open('序列化对象_pickle','wb') #w是写入的str,wb写入bytes f.write(j) #等价于pickle.dump(dic.f) f.close() >>>>> �}q (X nameqX alvinqX ageqKX sexqX malequ. 生成一个不可读文件,但是计算机可以解析
3、反序列化
f=open('序列化对象_pickle','rb') data=pickle.loads(f.read()) print(data['age']) >>>> 23
Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。
八、shelve模块
shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型
1.
#添加键值对到文件中,会生成三个文件,并写入字典内容 import shelve f = shelve.open(r'shelve1') # 目的:将一个字典放入文本 f={} f['stu1_info']={'name':'alex','age':'18'} f['stu2_info']={'name':'alvin','age':'20'} f['school_info']={'website':'oldboyedu.com','city':'beijing'} f.close()
执行结果:
会生成三个文件:shelvel.dat,shelve1.dir,shelve1.bak,其中shelvel.bak中内容如下:
'stu', (0, 49) 'stu1', (512, 50) 'school', (1024, 60)
九、xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
xml的格式如下,就是通过<>节点来区别数据结构的:
<?xml version="1.0"?> <data> #根 <country name="Liechtenstein"> #节点 <rank updated="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> #节点 <rank updated="yes">5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> #节点 <rank updated="yes">69</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data> xml数据
xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:
1.查询
import xml.etree.ElementTree as ET #ET为模块名的简写,自定义 tree=ET.parse('xml') #解析文件,相当于读取 root=tree.getroot() #获取根 print(root.tag) >>>>> data #遍历xml文档 for i in root: print(i.tag,i.attrib) #tag是标签,attrib属性 for j in i: print(j.tag,j.attrib) >>>>> country {'name': 'Liechtenstein'} rank {'updated': 'yes'} year {} gdppc {} neighbor {'name': 'Austria', 'direction': 'E'} neighbor {'name': 'Switzerland', 'direction': 'W'} country {'name': 'Singapore'} rank {'updated': 'yes'} year {} gdppc {} neighbor {'name': 'Malaysia', 'direction': 'N'} country {'name': 'Panama'} rank {'updated': 'yes'} year {} gdppc {} neighbor {'name': 'Costa Rica', 'direction': 'W'} neighbor {'name': 'Colombia', 'direction': 'E'}
#只遍历‘year’节点下的内容
for note in root.iter('year'):
print(note.tag,note.text)
>>>>>
year 2008
year 2011
year 2011
2.修改
import xml.etree.ElementTree as ET tree=ET.parse('xml') root=tree.getroot() for note in root.iter('year'): new_year=int(note.text)+1 note.text=str(new_year) note.set('updated','yes') #修改通过set,加个属性yes tree.write('xml') #最后写入,可以覆盖,也可以新建
3.删除
import xml.etree.ElementTree as ET tree=ET.parse('xml') root=tree.getroot()
for country in root.findall('country'): #对country节点进行遍历 rank = int(country.find('rank').text) #find找到rank if rank >50: root.remove(country) #移除 tree.write('xml') #最后写入,可以覆盖,也可以新建
4.XML的编写
import xml.etree.ElementTree as ET new_xml =ET.Element('namelist') #创建根 name = ET.SubElement(new_xml,'name',attrib={'enrolled':'yes'}) #创建子节点,并添加属性 age=ET.SubElement(name,'age',attrib={'checked':'NO'}) sex=ET.SubElement(name,'sex') sex.text='33' name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"}) #创建子节点 age=ET.SubElement(name2,'age') age.text='19' et=ET.ElementTree(new_xml) #生成文档对象 et.write('test_xml.xml',encoding='utf8',xml_declaration=True) ET.dump(new_xml)
执行结果
<?xml version='1.0' encoding='utf8'?> <namelist> <name enrolled="yes"> <age checked="NO" /> <sex>33</sex> </name> <name enrolled="no"> <age>19</age> </name> </namelist>