目录:
一、模块定义、导入、优化详解
二、内置模块详解之time与datatime模块
三、range模块
四、os模块
五、sys模块
六、shutil模块
七、zipfile模块
八、shelve模块
九、XML模块
十、Configparser模块
十一、Hashlib、Hmac模块
十二、正则表达式Re模块使用详解
一、模块定义、导入、优化详解
1.定义:
模块:用来从逻辑上组织python代码(包含变量、函数、类、逻辑:(实现一个功能)),本质就是.py结尾的python文件(文件名test.py,对应的模块名为test)。
包:用来从逻辑上组织模块,本质就是一个目录,区别是带一个__init__.py文件。
2.导入方法:
import module_name
导入多个模块:import module1_name,module2_name
from module_alex import * :此方法表示把模块中的所有代码复制到目标文件,所以调用方法和变量名时不需要加“模块名.变量”或“模块名.方法名”,而直接输入变量名和方法名即可。
from module_alex import * #全部导入 logger() #调用mudule_alex模块里的logger()方法,返回in the module_alex def logger(): #覆盖原logger print("in the main") logger() #返回in the main
如果不想被覆盖,可将方法命名为其它名称,格式为:
from module_alex import logger as logger_alex
from module_alex import logger as logger_alex #把logger方法命名为/logger_alex def logger(): print('in the main') logger()#返回in the main logger_alex() #返回in the module_alex
3.import本质(路径搜索和搜索路径)
import的本质是把导入的代码运行了一遍,把结果导入module_alex(统一赋值给变量module_alex),所以调用函数和变量时,直接用module_alex.name,module_alex.logger()的形式。
from module_alex import name:这句话的import相当于只把模块里的代码的name部分,放在当前文件位置,执行了一遍。如果此时再使用name变量,不需要加上模块名,直接使用即可。
导入模块的本质就是把python文件解释一遍(import test (test = test.py all code))
导入执行顺序:
import module_name --> module_name.py --> module_name.py的路径 --> sys.path
import搜索sys.path下的所有路径,所以如果导入的包不在当前路径。则需要把包所在的路径添加到sys.path里。
import os,sys os.path.abspath(__file__) #获取当前文件的绝对路径 os.path.dirname(os.path.abspath(__file__)) #获取目录名称 os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #上级目录 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) #将该目录添加进sys.path
导入包的本质就是执行该包的__init__.py文件
from . import test1 #从当前目录下导入test1(相对导入)
“.”代表__init__.py的当前目录,是相对路径
import package_test #执行这个目录下的__init__.py文件 package_test.test1.test()
4.导入优化
from module_test import test #相当于直接把module_test的代码粘贴过来,不用再查找,可直接调用,效率高
5.模块的分类
a.标准库(内置模块,python自带的)
b.开源模块(第三方模块)
c.自定义模块
二、内置模块详解之time与datatime模块
1.time与datatime
在python中,通常有几种方式来表示时间:1)时间戳 2)格式化的时间字符串 3)元祖(struct_time)共9个元素。由于python的time模块实现主要调用C库,所以各个平台可能有所不同。
时间戳:
数字单位为秒,从1970年1月1日到现在的时间间隔,换算成秒
换算成年:
2.格式化
3.元祖
元祖中的元素分别表示年、月、日、时、分、秒、一周的第几天、一年的第几天、是否是夏令时
UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。在中国为UTC+8。
DST(Daylight Saving Time)即夏令时。
时间戳(timestamp)的方式:通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行"type(time.time())",返回的是float类型。返回时间戳方式的函数主要
有time(),clock()等。
元组(struct_time)方式:struct_time元祖共有9个元素,返回struct_time的函数主要有gmtime(),localtime(),strptime()。
timezone:
所在时区比UTC早或晚多少秒,下图换算后表示比英国早8小时。
altzone:夏令时与UTC时间差值
time.daylight:是否使用了夏令时
sleep():睡几秒
gmtime():从时间戳转换为元组,括号内传入时间戳,如果不传入参数,默认把当前时间的秒转换为UTC时区的时间
localtime():把时间戳转换为元组,转换到本地时间元组形式。也可以通过传入参数指定多少秒。
import time x = time.localtime() print(x.tm_year) #返回当前年份 x = time.localtime(123123123) print(x.tm_year) #返回括号里时间戳的年份 print("this is 1973 day: %d" %x.tm_yday) #返回本年份的第几天
打印结果:
time.mktime(x):把元组变成时间戳
strftime与strptime:
格式自己定义,但是格式化的字母必须对应:
time.strftime("格式",struct_time) --> “格式化的字符串”
time.strptime("格式化的字符串","格式") --> struct_time:把trftime()反过来,得到结构化时间,得到元组:
print(time.strftime("%Y-%m-%d %H:%M:%S",x)) print(time.strptime('1973-11-26 08:52:03','%Y-%m-%d %H:%M:%S'))
打印结果:
asctime():传入元组,转换成eg格式。如果没有传变量,默认当前时间
ctime():把时间戳转换成上面的格式
datatime模块:基于time的高级封装
now():获取当前时间
#时间加减 import datetime print(datetime.datetime.now()) #返回2016-08-19 12:47:03.941925 print(datetime.date.fromtimestamp(time.time())) #时间戳直接转成日期格式 2016-08-19 print(datetime.datetime.now()) print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天 print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天 print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时 print(datetime.datetime.now() + datetime.timedelta(minutes = 30)) #当前时间+30分 c_time= datetime.datetime.now() print(c_time.replace(minute = 3,hour = 2)) #时间替换
三、range模块
random模块
random.random:随机浮点数(0-1)
random.randint():随机整数,括号里填范围,比如(1,3),在123里选
random.randrange():随机整数,顾头不顾尾,(3)表示(0,1,2)
random.choice():括号内传入序列,如字符串、列表
random.sample():第一个变量为序列,第二个为传入范围,如2表示取两位
random.uniform():浮点数,括号内指定区间
random.shuffle():洗牌,打乱顺序
随机生成验证码:
import random checkcode = '' #最后要生成的验证码 for i in range(4): #current = random.randint(1,9) current = random.randrange(0,4) #字母 if current == i: tmp = chr(random.randint(65,90)) #数字 else: tmp = random.randint(0,9) checkcode += str(tmp) print(checkcode)
四、os模块
斜杠转义方法:双斜杠或前面整体加r
创建递归目录
os.makedirs(r"C:acd")
环境变量:print(os.environ)
五、sys模块
六、shutil模块
copy文件用,可以压缩包
源代码:
#把f1复制给f2 import shutil f1 = open("本节笔记",encoding = "utf-8") f2 = open("笔记2",'w',encoding = "utf-8") shutil.copyfileobj(f1,f2)
另一种方法可直接复制,不必打开文件
shutil.copyfile("笔记2","笔记3")
shutil.copymode(src,dst):仅拷贝权限。内容、组、用户均不变
递归copy目录:
shutil.copytree("test4","new_test4")
压缩:
六、zipfile模块
解压:
import zipfile z = zipfile.ZipFile("day5.zip","w")
七、shelve模块
import shelve import datetime d = shelve.open('shelve_test') #打开一个文件 #————调用—————— print(d.get("name")) print(d.get("info")) print(d.get("date")) #————存入—————— info = {"age" : 22,"job" : "it"} name = {"alex","rain","test"} d["name"] = name #持久化 d["info"] = info d["date"] = datetime.datetime.now() d.close()
打印结果:
九、XML模块
xml的格式如下,就是通过<>节点来区别数据结构的:
getroot():打印xml文档根的名字:
import xml.etree.ElimentTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() print(root.tag) #遍历xml文档 for child in root: print(child.tag,child.attrib) for i in child: print(i.tag,i.text) #只遍历year节点 for node in root.iter("year") print(node.tag,node.text)
打印结果:
修改和删除
import xml.etree.ElimentTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() #修改 for node in root.iter('year'): new_year = int(node.text) + 1 #年份加一 node.text = str(new_year) node.set("updated","yes") #设置新属性 tree.write("xmltest.xml") #删除node for country in root.findall("country"): #寻找所有的country rank = int(country.find('rank').text) #寻找country下的rank内容 if rank > 50: root.remove(country) tree.write('output.xml')
创建:
import xml.etree.ElementTree as ET new_xml = ET.Element("personinfolist") personinfo = ET.SubElement(new_xml,"personinfo",attrib = {"enrolled":"yes"}) #子节点 name = ET.SubElement(personinfo,"name") name.text = "Alex Li" age = ET.SubElement(personinfo,"age",attrib = {"checked":"no"}) #personinfo的子节点 sex = ET.SubElement(personinfo,"sex") age.text = '56' personinfo2 = ET.SubElement(new_xml,"personinfo",attrib = {"enrolled":"no"}) name = ET.SubElement(personinfo2,"name") name.text = "Oldboy Ran" age = ET.SubElement(personinfo2,"age") age.text = '19' et = ET.ElementTree(new_xml) #生成文档对象 et.write("test.xml",encoding = "utf-8",xml_declaration = True) ET.dump(new_xml) #打印生成的格式
十、Configparser模块
load后会变成字典的格式:
ConfigParser模块:
用于生成和修改常见配置文档,当前模块的名称在python 3.x版本中变更为configparser
来看一个好多软件的常见文档格式如下:
生成:
import configparser config = configparser.ConfigParser() config["DEFAULT"] = {'ServerAliveInterval':'45', 'Compression':'yes', 'CompressionLevel':'9'} config['bitbucket.org'] = {} config['bitbucket.org']['user'] = 'hg' config['topsecret.server.com'] = {} topsecret['Host Port'] = '50022' #mutates the parser topsecret['ForwardX11'] = 'no' #same here config['DEFAULT']['ForwardX11'] = 'yes' with open('example.ini','w') as configfile: config.write(configfile)
读:
import configparser conf = configparser.ConfigParser() conf.read("example.ini") print(conf.sections()) #只打印节点,不打印default print(conf.default_section) #打印default print(conf['bitbucket.org']['user'])
打印结果:
循环节点:
修改:
remove完要重新写回去
十一、Hashlib,Hmac模块
Hashlib模块:用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法
import hashlib m = hashlib.md5() m.update(b"Hello") m.update(b"It's me") print(m.digest()) m.update(b"It's been a long time since last time we ...") print(m.digest()) #2进制格式hash print(len(m.hexdigest()))
md5算法:
import hashlib m = hashlib.md5() #生成md5对象 m.update(b"Hello") #b表示bytes数据类型 print(m.hexdigest()) #十六进制格式 m.update(b"It's me") print(m.hexdigest())#打印的代表It's me + Hello m.update(b"It's been a long time since that time we...") print(m.hexdigest()) m2 = hashlib.md5() #验证上面打印的是不是代表It's me + Hello m2.update(b"HelloIt's me") 与第8行打印结果相同 print(m2.hexdigest()) print(len(m.hexdigest())) #16进制格式hash
打印结果:
其他方法都一样:
hmac
import hmac h = hmac.new(b"12345","你是250".encode(encoding = "utf-8")) #第一个必须是bytes类型,后面要编码 print(h.digest()) print(h.hexdigest())
打印结果:
十二、正则表达式Re模块使用详解
re模块
正则表达式:只有一个功能:匹配字符串,动态模糊匹配。比如:所有姓陈的并且名字不超过2个字的查出来
有返回值就表示匹配到了,group查看匹配到了什么。
匹配全部:
匹配以R开头以a结尾的字母段(如果有多个Ronghua,只会取第一个)
包含大写:
?:匹配前一个字符1次或0次
注意,如果被匹配的字符前面是2个a,那么aaa?中的前两个a必有,最后一个可以匹配0个,所有匹配到的字符是2个a,而如果被匹配的字符前面是1个a,不符合aaa?中前两个a的条件,所以匹配后三个a
{m}表示匹配多少次,下例为匹配3个数字
匹配1-3次
匹配所有符合要求的字符:findall,查询时不加group
|:匹配|左边或右边的字符(从左往右):
匹配所有还是findall
匹配两次abc
注意:如果两个abc不相连报错
匹配两次abc,两次||=
|为转移管道符
A等效于^
等效于$
D:匹配非数字
w:大小写字母数字
W:只有特殊字符
s:空格换行制表符
分组匹配:
匹配身份证号:
split:
空的表示1和2之间的
sub:替换
把所有数字替换成|:
匹配两次:
匹配
re.I:忽略大小写