Python常用的模块和包
1. 导入包和模块
1.1 import导入模块
1)导入模块
模块可以包含可执行的语句和函数的定义,这些语句的作用是初始化模块,它们只在模块第一次遇到导入语句import时才执行。
import语句可以在程序中的任意位置使用,且在第一次导入之后就将模块名加载到内存中了,后续对于同样模块的import仅仅是对已经加载到内存中的模块对象增加了一次引用,不会重新执行模块内的语句。
# 只在第一次导入时才执行xxoo.py内的代码, import xxoo
2)定义模块别名
可以在导入模块后使用as关键字定义模块别名,定义别名的目的是为了方便使用。
import xxoo.py as fuck fuck.read1()
3)第一次导入模块执行的事件
为源文件(xxoo.py)创建新的名称空间,在xxoo.py中定义的函数和方法若是使用到了global时访问的就是这个名称空间。
创建名字xxoo来引用该命名空间,这个名字和变量名没有什么区别。
重复导入会直接引用内存中已经加载好的结果。
4)被导入的模块具有独立的名称空间
每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做是全局名称空间。
这样在编写自己的模块时,就不用担心定义在自己模块中的全局变量会在被导入时,与使用者的全局变量冲突。
1.2 from ... import ...
from ... import .. 是将模块中的名字直接导入到当前的名称空间中,所以在当前名称空间中,直接使用名字就可以,无需加前缀 . 的形式。
但是这样容易与当前执行文件中的名称冲突。执行文件若有与模块同名的变量或者函数名,会有覆盖效果。
1)使用as别名的形式
from xxoo import fuck as readread()
2)一行导入多个
from xxoo import fuck,read2,name
3)from ... import *
把模块中所有的不是以下划线(_)开头的名称都导入到当前位置。
大部分情况下不应该使用这种导入方式,因为 * 不知道导入什么名字,可能会覆盖掉之前已经定义的名字。
可以使用__all__来控制 * (用来发布新版本),在模块文件中新增一行:
__all__=['money','read1'] # 这样在另外一个文件中用from spam import * 就这能导入列表中规定的两个名字
1.3 模块搜索路径
1)模块的查找顺序
模块查找的顺序是:内存中已经加载的模块 ——> 内置模块 ——> sys.path路径中包含的模块
- 在第一次导入某个模块时,会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用
- python解释器在启动时会自动加载一些模块到内存中,可以使用sys.models来查看
- 如果没有,解释器则会查找同名的内置模块
- 如果还没有,就从sys.path给出的目录列表中依次寻找模块文件
2)sys.path
- 自定义的模块不应该与系统内置模块重名。
- 在初始化之后,python程序可以修改sys.path,路径放到前面的优先于标准库被加载。
- 搜索时按照sys.path中从左到右的顺序查找,sys.path中可能会包含 .zip 归档文件,python会把 .zip 归档文件当成一个目录去处理。
3)windows下的路径
- windows下的路径开头要加 r,否则会出现语法错误。
sys.path.insert(0,r'C:\Users\Administrator\PycharmProjects\a')
2. time模块
2.1 time表示时间的几种格式
时间戳是机器能够识别的时间,字符串是人能看懂的时间,元组则是用来操作时间的。
#导入时间模块 >>>import time
#时间戳 >>>time.time() 1500875844.800804
#时间字符串 >>>time.strftime("%Y-%m-%d %X") '2017-07-24 13:54:37' >>>time.strftime("%Y-%m-%d %H-%M-%S") '2017-07-24 13-55-04'
#时间元组:localtime将一个时间戳转换为当前时区的struct_time time.localtime() time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=13, tm_min=59, tm_sec=37, tm_wday=0, tm_yday=205, tm_isdst=0)
2.2 时间格式的转换
1)时间戳 ——> 结构化时间
- UTC时间:英国伦敦当地时间
- 北京时间:与UTC时间相差8小时,北京时间=UTC时间+8小时
# 时间戳 --> 结构化时间 # time.gmtime(时间戳) # UTC时间 # time.localtime(时间戳) # 当地时间 >>>time.gmtime(1500000000) time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0) >>>time.localtime(1500000000) time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
2)结构化时间 ——> 时间戳
#结构化时间-->时间戳 #time.mktime(结构化时间) >>>time_tuple = time.localtime(1500000000) # 将时间戳转换成结构化时间 >>>time.mktime(time_tuple) # 将结构化时间转换成时间戳 1500000000.0
3)结构化时间 ——> 字符串时间
#结构化时间-->字符串时间 # time.strftime("格式定义","结构化时间") 结构化时间参数若不传,则显示当前时间
>>>time.strftime("%Y-%m-%d %X") '2017-07-24 14:55:36' >>>time.strftime("%Y-%m-%d",time.localtime(1500000000)) '2017-07-14'
4)字符串时间 ——> 结构化时间
# 字符串时间-->结构化时间 # time.strptime(时间字符串,字符串对应格式) >>>time.strptime("2017-03-16","%Y-%m-%d") time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1)
>>>time.strptime("07/24/2017","%m/%d/%Y") time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)
5)其他相关
#结构化时间 --> %a %b %d %H:%M:%S %Y串 #time.asctime(结构化时间) 如果不传参数,直接返回当前时间的格式化串 >>>time.asctime(time.localtime(1500000000)) 'Fri Jul 14 10:40:00 2017' >>>time.asctime() 'Mon Jul 24 15:18:33 2017'
#时间戳 --> %a %b %d %H:%M:%S %Y串 #time.ctime(时间戳) 如果不传参数,直接返回当前时间的格式化串 >>>time.ctime() 'Mon Jul 24 15:19:07 2017' >>>time.ctime(1500000000) 'Fri Jul 14 10:40:00 2017'
2.3 计算时间差
import time true_time=time.mktime(time.strptime('2017-09-11 08:30:00','%Y-%m-%d %H:%M:%S')) time_now=time.mktime(time.strptime('2017-09-12 11:00:00','%Y-%m-%d %H:%M:%S')) dif_time=time_now-true_time struct_time=time.gmtime(dif_time) print('过去了%d年%d月%d天%d小时%d分钟%d秒'%(struct_time.tm_year-1970,struct_time.tm_mon-1, struct_time.tm_mday-1,struct_time.tm_hour, struct_time.tm_min,struct_time.tm_sec))
2.4 datetime
1)获取当前日期和时间
from datetime import datetime print(datetime.now()) # datetime.now()返回当前日期和时间,其类型是datetime ''' 结果:2018-12-04 21:07:48.734886 '''
2)获取指定日期和时间
from datetime import datetime dt = datetime(2018,5,20,13,14) print(dt) ''' 结果:2018-05-20 13:14:00 '''
3)datetime转换为timestamp
from datetime import datetime dt = datetime.now() new_timestamp = dt.timestamp() print(new_timestamp) ''' 结果:1543931750.415896 '''
4)timestamp转换为datetime
import time from datetime import datetime new_timestamp = time.time() print(datetime.fromtimestamp(new_timestamp))
5)str转换为datetime
from datetime import datetime t = datetime.strptime('2018-4-1 00:00','%Y-%m-%d %H:%M') print(t) ''' 结果: 2018-04-01 00:00:00 '''
6)datetime转换为str
from datetime import datetime now = datetime.now() print(now.strftime('%a, %b %d %H:%M')) Mon, May 05 16:28
7)datetime加减
from datetime import datetime, timedelta # 主要要导入timedelta这个类 now = datetime.now() now datetime.datetime(2015, 5, 18, 16, 57, 3, 540997) now + timedelta(hours=10) datetime.datetime(2015, 5, 19, 2, 57, 3, 540997) now - timedelta(days=1) datetime.datetime(2015, 5, 17, 16, 57, 3, 540997) now + timedelta(days=2, hours=12) datetime.datetime(2015, 5, 21, 4, 57, 3, 540997)
8)注意
- datetime表示的时间需要时区信息才能确定一个特定的信息,否则只能视为本地时间
- 如果要存储datetime,最佳方法是将其转换为timestamp再存储,因为timestamp的值与时区完全无关
3. random模块
import random # 随机小数 random.random() # 大于0且小于1之间的小数 (0, 1) random.uniform(1,3) # 大于1小于3的小数 (1, 3) # 随机整数 random.randint(1,5) # 大于等于1且小于等于5之间的整数 [1, 5] random.randrange(1,3) # 大于等于1且小于3之间的整数 [1, 3) random.randrange(1,10,2) # 大于等于1且小于10之间的奇数 # 随机选择一个返回 random.choice([1,'23',[4,5]]) # 1或者23或者[4,5] # 随机选择多个返回,返回的个数为函数的第二个参数 random.sample([1,'23',[4,5]],2) # 列表元素任意2个组合 # 打乱列表的顺序 item = [1, 3, 5, 7, 9] random.shuffle(item) # 将传入的对象内容顺序打乱 print(item)
- 实现5位随机验证码功能
# 实现5位随机验证码功能: def v_code(): ret = "" for i in range(5): num = random.randint(0,9) alp = chr(random.randint(65, 90)) # ASCII码表的A到Z依次对应于65到90 res = str(random.choice([num, alp])) # 这里用了str将可能出现的数字转换为str类型 ret += res return ret print(v_code())
4. os模块
- os模块是与操作系统交互的一个接口
4.1 文件夹相关
import os os.makedirs('dirname1/dirname2') # 可生成多层递归目录 os.removedirs('dirname1') # 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') # 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') # 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') # 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
4.2 文件相关
import os os.remove() # 删除一个文件 os.rename("oldname", "newname") # 重命名文件/目录 os.stat("path/filename") # 获取文件/目录信息
4.3 操作系统差异相关
import os
os.sep # 输出操作系统特定的路径分隔符,win下为\\ , linux下为/ os.linesep # 输出当前平台使用的行终止符,win下为\t\n , Linux下为\n os.pathsep # 输出用于分割文件路径的字符串 ,win下为; Linux下为: os.name # 输出字符串指示当前使用平台,win下为"nt" , Linux下为"posix"
4.4 执行系统命令相关
import os os.system("bash command") # 运行shell命令,直接显示 os.popen("bash command").read() # 运行shell命令,获取执行结果 os.environ # 获取系统环境变量
4.5 path系列
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.exists(path) # 如果path存在,返回True,如果path不存在,返回False os.path.isabs(path) # 如果path是绝对路径,返回True os.path.isfile(path) # 如果path是一个存在的文件,返回Ture,否则返回False os.path.isdir(path) # 如果path是一个存在的目录,这返回True,否则返回False os.path.join(path1, path2,···) # 将多个路径组合后返回 os.path.getatime(path) # 返回path所指向的文件或者目录的最后存取时间 os.path.getmtime(path) # 返回path所指向的文件或者目录的最后修改时间 os.path.getsize(path) # 返回文件的大小
4.6 工作路径
import os
os.getcwd() # 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") # 改变当前脚本工作目录;相当于shell下cd os.curdir # 返回当前目录: ('.') os.pardir # 获取当前目录的父目录字符串名:('..')
4.7 start
- os.stat('path/filename') 获取 文件/目录信息 的结构说明
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)是创建时间(详细信息参见平台的文档)
5. sys模块
- sys模块是python解释器交互的一个接口
sys.argv # 命令行参数List,第一个元素是程序本身路径 sys.exit(n) # 退出程序,正常退出时exit(0),错误退出sys.exit(1) sys.version # 获取Python解释程序的版本信息 sys.path # 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform # 返回操作系统平台名称
- 进度条
# 进度条 import time for i in range(30): sys.stdout.write("#") # 其实print函数在内部调用的就是这种形式 time.sleep(0.2) sys.stdout.flush() # 这里的刷新是将缓冲区的文本信息打印到屏幕上
6. json&pickle模块
6.1 序列化&反序列化
- 序列化简单来说就是将python的数据结构存储到文件中
- 反序列化就是把存储到文件中的数据结构重新加载恢复出来
6.2 json的dump&load
import json dic = {"name": "hgzero"} # dump f = open("new_welcome", "w", encoding='utf-8') json.dump(dic, f) # 第一个参数是要转换的数据类型,第二个参数是一个文件句柄,也就是要存到那个文件中 # load f_read = open("new_welcome", "r", encoding='utf-8') data = json.load(f_read) # load可以从一个文件中读取内容
6.3 json的dumps&loads
import json dic = {"name": "hgzero"} # json的序列化和反序列化:(json可以在任何支持json的编程语言间传输) dic_str = json.dumps(dic) # json的dumps方法可以将传入的数据转换成字符串 f = open("new_welcome", "w") f.write(dic_str) f_read = open("new_welcome", "r") data = json.loads(f_read.read()) # json的loads方法可以将json格式的字符串还原成原来的格式 print(data) # 以上就相当于:data = json.load(f_read) # json字符串的规范: # 数据类型中全部使用双引号 "" # 注意:只要符合json规范,就能loads,而不需要先dumps后loads
6.4 pickle
# pickle的序列化和反序列化:(pickle中是以字节形式保存,且只能在python中使用) # pickle可以支持python中的全部数据类型(包括函数、类) # pickle的用法和使用json完全一样
7. hashlib模块
import hashlib # md5加密 obj = hashlib.md5() # 对字符串进行加密(字符串要进行编码) obj.update("hello".encode("utf8")) obj.update("admin".encode("utf8")) # 如果连续updata了多次,相当于进行了两段字符串的拼接 这里相当于加密了 helloadmin # obj.update("helloadmin".encode("utf8")) # dbba06b11d94596b7169d83fed72e61b # 打印出obj对象中保存的加密信息 print(obj.hexdigest()) # 其他加密类型的加密 # sha256 的加密和md5的使用格式一样,仅需要将md5换成sha256 # sha1 , sha224 , sha256 , sha384 , sha512 , md5 # sha1加密 obj2 = hashlib.sha1() # 对字符串加密 obj2.update("hgzerowzh".encode('utf-8')) # 打印出obj对象中保存的加密信息 print(obj2.hexdigest())