模块
一、定义:
模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),
本质就是.py结尾的python文件(文件名:test.py,对应模块名:test)
包:用来从逻辑上组织模块的,本质就是一个目录(必须带有一个__init__.py的文件)
二、导入方法
import module_alex,
调用:print(module_alex.name)
module_alex.say_hello()
导入多个模块:import module1_name,import module2_name
把module_alex中的所有代码导入:from module_alex import *(不建议使用*,
它的本质是复制maodule_alex中的代码到当前程序,变量有重复的话执行当前程序的变量)
from module_alex import logger as logger_alex (起个别名)
导入多个:from module_alex import m1,m2,m3
三、import本质(路径搜索和搜索路径)
import module_alex将module_alex的所有代码解释一遍并赋值给一个变量module_alex,调用通过module_alex.***的形式
(import test test="test.py all code")
(from test import name name="code")
导入模块的本质就是把python文件解释一遍。
import module_alex--->module_alex.py(是文件就一定有路径)---->module_alex.py的路径---->sys.path(先在当前位置找,再在系统环境变量中找)
导入包的本质就是执行该包下面的__init__.py文件
四、导入优化
from module_test import test
main.py
1 import sys,os 2 print(sys.path) 3 4 x=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 5 sys.path.append(x) 6 import module_alex 7 module_alex.say_hello()
__init__.py
1 print("from the package_test") 2 3 #import test1 #test="test1.py all code".test1.test() 4 from.import test1 #相对导入,从当前目录下导入test1,相对于__init__的路径
test1.py
1 def test(): 2 print("in the test1")
module_test.py
1 def test(): 2 print("in the module_test")
test.py
1 import module_test 2 #from module_test import test 3 def logger(): 4 module_test.test() 5 print('in the logger') 6 7 def search(): 8 module_test.test() 9 print("in the search")
module_alex.py
1 name="alex" 2 def say_hello(): 3 print("hello alex") 4 def logger(): 5 pass 6 def running(): 7 pass
p_test.py
1 import package_test 2 #1.run __init__.py--->test1="test1.py all code".test1 3 4 package_test.test1.test()
五、模块的分类:
a:标准库(内置模块)、b:开源模块(第三方模块)、c:自定义模块
1.time与datetime
在Python中,通常有这几种方式来表示时间:1)时间戳2)格式化的时间字符串3)元组(struct_time)共九个元素。由于Python的time模块实现主要调用C库,所以各个平台可能有所不同。
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()。
import time
print(time.localtime())
'''--->time.struct_time(tm_year=2017, tm_mon=10, tm_mday=24,
tm_hour=10, tm_min=36, tm_sec=20, tm_wday=1, tm_yday=297, tm_isdst=0)'''
time:
1 import time 2 print(time.localtime()) 3 '''--->time.struct_time(tm_year=2017, tm_mon=10, tm_mday=24, 4 tm_hour=10, tm_min=36, tm_sec=20, tm_wday=1, tm_yday=297, tm_isdst=0)''' 5 6 #Variables: 7 print(help(time)) 8 print(time.timezone) # difference in seconds between UTC and local standard time 9 print(time.altzone) #difference in seconds between UTC and local DST time 10 print(time.daylight) #whether local time should reflect DST 11 #Functions: 12 print(time.time()) # return current time in seconds since the Epoch as a float 13 time.sleep(2) # delay for a number of seconds given as a float 14 print(time.gmtime())#将时间戳转化为struct_time,不传入参数的话将本地时间换算成UCT时间,传入参数的话,"1970"+参数 15 print(time.localtime())#将时间戳转化为struct_time,不传入参数的话就是本地时间,传入参数同上,不过hour+8 16 17 x=time.localtime() 18 print(x.tm_year) #提取"年" 19 20 print(time.mktime(x)) #元组形式转化为时间戳 21 print(time.strftime("%Y-%m-%d %H:%M:%S",x)) #元组形式转化为格式化字符串 22 #%Y相当于x.tm_year %m相当于x.tm_mon 23 print(time.strptime("2017-10-24 13:36:46","%Y-%m-%d %H:%M:%S")) #格式化字符串转化为元组形式 24 #以后面的格式到前边找对应的值,x.tm_year=2017,x.tm_mon=10 25 26 print(time.asctime())#将元组转化为字符串的格式,不写参数传入的就是本地时间 27 print(time.ctime())#将时间戳转化为字符串的格式,不写参数传入的就是本地时间 28 29 import datetime 30 print(datetime.datetime.now()) # 返回 2017-10-24 14:52:46.098161 31 print(datetime.date.fromtimestamp(time.time()) ) # 时间戳直接转成日期格式 2017-10-24 32 print("-----") 33 print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天 34 print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天 35 print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时 36 print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分 37 print("-----") 38 c_time = datetime.datetime.now() 39 print(c_time.replace(minute=3,hour=12)) #时间替换
strftime(“格式”,struct_time)--->“格式化的字符串”
strptime(“格式化的字符串”,“格式”)--->struct_time
格式参照:
%
a 本地(locale)简化星期名称
%
A 本地完整星期名称
%
b 本地简化月份名称
%
B 本地完整月份名称
%
c 本地相应的日期和时间表示
%
d 一个月中的第几天(
01
-
31
)
%
H 一天中的第几个小时(
24
小时制,
00
-
23
)
%
I 第几个小时(
12
小时制,
01
-
12
)
%
j 一年中的第几天(
001
-
366
)
%
m 月份(
01
-
12
)
%
M 分钟数(
00
-
59
)
%
p 本地am或者pm的相应符
%
S 秒(
01
-
61
)
%
U 一年中的星期数。(
00
-
53
星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第
0
周。
%
w 一个星期中的第几天(
0
-
6
,
0
是星期天)
%
W 和
%
U基本相同,不同的是
%
W以星期一为一个星期的开始。
%
x 本地相应日期
%
X 本地相应时间
%
y 去掉世纪的年份(
00
-
99
)
%
Y 完整的年份
%
Z 时区的名字(如果不存在为空字符)
%
%
‘
%
’字符
2.random模块
1 import random 2 print(random.random())#随机浮点值0-1之间 3 4 print(random.randint(1,3))#随机1-3之间的整数,3能取到 5 #random.randint()的函数原型为:random.randint(a, b),用于生成一个指定范围内的整数。 6 # 其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b 7 8 print(random.randrange(1,3))#随机1-3之间的整数,3不能取到,1能取到 9 #random.randrange的函数原型为:random.randrange([start], stop[, step]), 10 # 从指定范围内,按指定基数递增的集合中 获取一个随机数。如:random.randrange(10, 100, 2), 11 # 结果相当于从[10, 12, 14, 16, ... 96, 98]序列中获取一个随机数。 12 # random.randrange(10, 100, 2)在结果上与 random.choice(range(10, 100, 2) 等效。 13 14 print(random.choice("hello"))#序列,字符串,列表,元组 15 # 其函数原型为:random.choice(sequence)。参数sequence表示一个有序类型。 16 # 这里要说明一下:sequence在python不是一种特定的类型,而是泛指一系列的类型。 17 # list, tuple, 字符串都属于sequence。有关sequence可以查看python手册数据模型这一章。 18 19 print(random.sample("hello",4))#第一个变量序列,字符串,列表,元组,第二个定义一个长度,随机取几位返回 20 #random.sample的函数原型为:random.sample(sequence, k),从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列。 21 list = [1, 2, 3, 4, 5, 6, 7, 8] 22 slice = random.sample(list, 5) # 从list中随机获取5个元素,作为一个片断返回 23 print(slice) 24 print(list) # 原有序列并没有改变 25 26 print(random.uniform(1,3))#random不能指定区间,uniform可以指定 27 28 l=[1,2,3,4,5,6] 29 random.shuffle(l)#洗牌功能 30 print(l) 31 print("------") 32 import random 33 # 随机整数: 34 print(random.randint(0, 99)) # 70 35 # 随机选取0到100间的偶数: 36 print(random.randrange(0, 101, 2)) # 4 37 # 随机浮点数: 38 print(random.random()) # 0.2746445568079129 39 print(random.uniform(1, 10)) # 9.887001463194844 40 # 随机字符: 41 print(random.choice('abcdefg%^*f')) # f 42 # 多个字符中选取特定数量的字符: 43 print(random.sample('abcdefghij', 3)) # ['f', 'h', 'd'] 44 # 随机选取字符串: 45 print(random.choice(['apple', 'pear', 'peach', 'orange', 'lemon'])) # apple 46 # 洗牌# 47 items = [1, 2, 3, 4, 5, 6, 7] 48 print(items) # [1, 2, 3, 4, 5, 6, 7] 49 random.shuffle(items) 50 print(items) # [1, 4, 7, 2, 5, 3, 6] 51 print("======") 52 #验证码 53 checkcode="" 54 for i in range(4): 55 #i=0 56 current=random.randrange(0,4) 57 #字母 58 if current==i: 59 tmp=chr(random.randint(65,90)) 60 #数字 61 else: 62 tmp=random.randint(0,9) 63 checkcode+=str(tmp) 64 print(checkcode)
3.os模块
1 import os 2 print(os.getcwd())#获取当前工作目录,即当前python脚本工作的目录路径 3 # os.chdir("E:\\pycharm\\s14\\") 4 os.chdir(r"E:\pycharm\s14") 5 print(os.getcwd())# 改变当前脚本工作目录;相当于shell下cd 6 print(os.curdir) # 返回当前目录: ('.') 7 print(os.pardir) #获取当前目录的父目录字符串名:('..') 8 #os.makedirs(r'E:\a\b\c\d') # 可生成多层递归目录 9 #os.removedirs(r'E:\a\b\c\d') #若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推,清理空文件夹 10 #os.mkdir(r'E:\a\b') # 生成单级目录;相当于shell中mkdir dirname 11 #os.rmdir(r'E:\a\b') # 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname 12 print(os.listdir(".")) #列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印--> 13 # ['.idea', 'day1', 'day2', 'day3', 'day4', 'day5'] 14 #os.remove() # 删除一个文件 15 #os.rename(r"E:\pycharm\s14\day5\y_test.py",r"E:\pycharm\s14\day5\p_test.py") #重命名文件/目录 16 print(os.stat('day5')) #获取文件/目录信息 17 print(os.sep)#输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" 18 print(os.linesep) # 输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n" 19 #print(os.environ)#获取系统环境变量 20 print(os.pathsep) #输出用于分割文件路径的字符串 windows中';' 21 print(os.name) #输出字符串指示当前使用平台。win->'nt'; Linux->'posix' 22 #os.system("dir") #运行shell命令,直接显示 23 #os.system("ipconfig /all") 24 print(os.path.abspath(r"E:\pycharm\day5\os_moduel\os.py")) #返回规范化的绝对路径 25 print("=====") 26 print(os.path.split(r"E:\a\b\c\d.txt")) # 将path分割成目录和文件名二元组返回 27 print(os.path.dirname(r"E:\a\b\c\d.txt")) #返回path的目录。其实就是os.path.split("path")的第一个元素 28 print(os.path.basename(r"E:\a\b\c\d.txt")) # 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。 29 # 即os.path.split("path")的第二个元素 30 #以上三中方法都可以在目录不存在的情况下进行 31 print(os.path.exists(r"E:\a")) # 如果path存在,返回True;如果path不存在,返回False 32 print(os.path.isabs(r"a\b")) # 如果path是绝对路径,返回True 33 print(os.path.isfile(r"E:\a\1.txt")) # 如果path是一个存在的文件,返回True。否则返回False,不存在文件False 34 print(os.path.isdir(r"E:\a")) # 如果path是一个存在的目录,则返回True。否则返回False,不存在目录False 35 print(os.path.join(r"C:",r"a",r"b",r"a.txt"))# 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 36 print(os.path.getatime(r"E:\a\1.txt")) # 返回path所指向的文件或者目录的最后存取时间 ,文件必须存在 37 print(os.path.getmtime(r"E:\a\1.txt") ) #返回path所指向的文件或者目录的最后修改时间
更多https://docs.python.org/2/library/os.html?highlight=os#module-os
4.sys模块
1 import sys 2 print(sys.argv) # 命令行参数List,,在终端运行后加参数,第一个元素是程序本身路径 3 #print(sys.exit()) #退出程序,正常退出时exit(0) 4 print(sys.version) #获取Python解释程序的版本信息 5 print(sys.maxsize) 6 print(sys.path) #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 7 print(sys.platform) #返回操作系统平台名称 8 print(sys.stdout.write('please:')) 9 val = sys.stdin.readline()[:-1]
5.shutil模块
http://www.cnblogs.com/wupeiqi/articles/4963027.html
高级的 文件、文件夹、压缩包 处理模块
shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中,可以部分内容
shutil.copyfile(src, dst)
拷贝文件
shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变
shutil.copystat(src, dst)
拷贝状态的信息,包括:mode bits, atime, mtime, flags
shutil.copy(src, dst)
拷贝文件和权限
shutil.copy2(src, dst)
拷贝文件和状态信息
shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件
例如:copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件
shutil.move(src, dst)
递归的去移动文件
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对象
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() 12 z.close()
1 import tarfile 2 3 # 压缩 4 tar = tarfile.open('your.tar','w') 5 tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip') 6 tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip') 7 tar.close() 8 9 # 解压 10 tar = tarfile.open('your.tar','r') 11 tar.extractall() # 可设置解压地址 12 tar.close()
1 import shutil 2 # f1=open("本节笔记",encoding="utf-8") 3 # f2=open("笔记2","w",encoding="utf-8") 4 # shutil.copyfileobj(f1,f2) 5 6 #shutil.copyfile("笔记2","笔记3") 7 8 #shutil.make_archive("shutil_archive_test","zip","E:\pycharm\s14\day5") 9 10 import zipfile 11 z = zipfile.ZipFile("day5.zip","w") 12 z.write("p_test.py") 13 print("---") 14 z.write("笔记2") 15 z.close()
6.shelve模块
shelve模块是一个简单的key-value将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。
1 import shelve,datetime 2 3 d = shelve.open('shelve_test') # 打开一个文件 4 5 # info={"age":22,"salary":"50w"} 6 # 7 # name = ["alex", "rain", "test"] 8 # d["test"] = name # 持久化列表 9 # d["name"] = name # 持久dict 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"))
7.xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,
大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
xml的格式如下,就是通过<>节点来区别数据结构的:
1 xml version='1.0' encoding='utf-8'?> 2 <data> 3 <country name="Liechtenstein"> 4 <rank updated="yes">2rank> 5 <year updated_by="alex">2009year> 6 <gdppc>141100gdppc> 7 <neighbor direction="E" name="Austria" /> 8 <neighbor direction="W" name="Switzerland" /> 9 country> 10 <country name="Singapore"> 11 <rank updated="yes">5rank> 12 <year updated_by="alex">2012year> 13 <gdppc>59900gdppc> 14 <neighbor direction="N" name="Malaysia" /> 15 country> 16 <country name="Panama"> 17 <rank updated="yes">69rank> 18 <year updated_by="alex">2012year> 19 <gdppc>13600gdppc> 20 <neighbor direction="W" name="Costa Rica" /> 21 <neighbor direction="E" name="Colombia" /> 22 <info> 23 <population>8population> 24 <size>960size> 25 info> 26 country> 27 data>
xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml
1 import xml.etree.ElementTree as ET 2 3 tree = ET.parse("xmltest.xml") #写上要处理的文件名 4 root = tree.getroot() 5 print(root) 6 print(root.tag) #标签名 7 8 # 遍历xml文档 9 for child in root: 10 print(child.tag, child.attrib) #子标签,attrib属性 11 for i in child: 12 print(i.tag, i.text) 13 for j in i: 14 print(j.tag,j.text) 15 16 # # 只遍历year 节点 17 # for node in root.iter('year'): 18 # 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 #把年+1 9 # node.text = str(new_year) 10 # node.set("updated_by", "alex") #加属性 11 # 12 # tree.write("xmltest.xml") 13 14 # 删除node 15 for country in root.findall('country'): 16 rank = int(country.find('rank').text) 17 if rank > 50: 18 root.remove(country) 19 20 tree.write('output.xml')
自己创建xml文档
1 import xml.etree.ElementTree as ET 2 3 new_xml = ET.Element("personinfolist") #根节点 4 personinfo = ET.SubElement(new_xml, "personinfo", attrib={"enrolled": "yes"}) #new_xml的子节点 5 name = ET.SubElement(personinfo, "name") 6 name.text="alex" 7 age = ET.SubElement(personinfo, "age", attrib={"checked": "no"})#personinfo的子节点 8 sex = ET.SubElement(personinfo, "sex") 9 age.text = '33'#赋值 10 personinfo2 = ET.SubElement(new_xml, "personinfo", attrib={"enrolled": "no"}) 11 name = ET.SubElement(personinfo2, "name") 12 name.text="jyh" 13 age = ET.SubElement(personinfo2, "age") 14 age.text = '19' 15 16 et = ET.ElementTree(new_xml) # 生成文档对象 17 et.write("test.xml", encoding="utf-8", xml_declaration=True) #xml_declaration=True,声明xml格式 18 19 ET.dump(new_xml) # 打印生成的格式
8.PyYAML模块
Python也可以很容易的处理ymal文档格式,只不过需要安装一个模块,参考文档:http://pyyaml.org/wiki/PyYAMLDocumentation ,可以做配置文件
9.ConfigParser模块
用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 configparser。
来看一个好多软件的常见文档格式如下(与MySQL格式一样)
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 #ConfigParser in python 2.x 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 11 config['topsecret.server.com'] = {} 12 config['topsecret.server.com']['Host Port'] = '50022' # mutates the parser 13 config['topsecret.server.com']['ForwardX11'] = 'no' # same here 14 15 config['DEFAULT']['ForwardX11'] = 'yes' 16 17 with open('example.ini', 'w') as configfile: 18 config.write(configfile)
写完了还可以再读出来哈。
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'
configparser增删改查语法
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"))
10.hashlib模块
用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法(都是基于hash的,SHA比MD5更安全)
1 import hashlib 2 m=hashlib.md5() 3 m.update(b"Hello") 4 print(m.hexdigest()) #16进制的格式 5 m.update("It's me天王盖地虎".encode(encoding="utf-8")) #实际上是“HelloIt's me天王盖地虎” 6 print(m.hexdigest()) 7 #m.update(b"It's been a long time since we spoken...") 8 #print(m.hexdigest()) 9 10 m2=hashlib.md5() 11 m2.update(b"HelloIt's me") 12 print(m.hexdigest()) 13 14 s2=hashlib.sha1() 15 s2.update(b"HelloIt's me") 16 print(s2.hexdigest()) 17 print("====") 18 import hmac 19 h=hmac.new(b"12345","you are 250你是".encode(encoding="utf-8"))#在3.0里,encode一下就是bytes了 20 print(h.hexdigest())
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())
还不够吊?python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;
一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,
这样就能验证消息的真实性,及发送者的合法性了。
1 import hmac 2 h = hmac.new(b'天王盖地虎', b'宝塔镇河妖') 3 print h.hexdigest()
更多关于md5,sha1,sha256等介绍的文章看这里https://www.tbs-certificates.co.uk/FAQ/en/sha256.html
11.正则表达式
使用不难,难在匹配格式。爬虫需要精通。
常用正则表达式符号
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 11 12 13 '\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的 14 '\Z' 匹配字符结尾,同$ 15 '\d' 匹配数字0-9 16 '\D' 匹配非数字 17 '\w' 匹配[A-Za-z0-9] 18 '\W' 匹配非[A-Za-z0-9] 19 's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t' 20 21 '(?P...) ' 分组匹配 re.search("(?P[0-9]{4})(?P ","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}[0-9]{2})(?P [0-9]{4})
========================================
========================================
split套路
sub套路
最常用的匹配语法:
1.re.match 从头开始匹配
2.re.search 匹配包含
3.re.findall 把所有匹配到的字符放到以列表中的元素返回
4.re.splitall 以匹配到的字符当做列表分隔符
5.re.sub 匹配字符并替换
与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",
那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,
转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。
同样,匹配一个数字的"\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
仅需轻轻知道的几个匹配模式
1.re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
2.M(MULTILINE): 多行模式,改变
'^'
和
'$'
的行为
3.S(DOTALL): 点任意匹配模式,改变
'.'
的行为
本节作业
开发一个简单的python计算器
- 实现加减乘除及拓号优先级解析
- 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,
- 必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致
思路:
1.先用正则表达式匹配到最里层的括号所包括的不带括号的表达式
2.再把数据量变小(判断里面是否有括号,把加减运算和乘除运算单独放到两个函数里去做)
hint:
re.search(r'\([^()]+\)',s).group()
'(-40/5)'