一 time & datetime
在Python中,通常有如下几种方式来表示时间:
- 时间戳(timestamp): 通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行"type(time.time())",返回的是float类型。
- 格式化的时间字符串(Format String)
- 结构化的时间(struct_time): struct_time元祖共有9个元素(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
>>> import time #-------------------------以下分别是三种形式的时间-----------------------# >>> print(time.time()) #时间戳 1509802396.6130548 >>> print(time.strftime('%Y-%m-%d %X')) #格式化的时间字符串,默认按当前时间(time.localtime())进行格式化 2017-11-04 21:34:03 >>> print (time.strftime('%a %b %d %H:%M:%S %Y')) #格式化的时间字符串,同上一个 Sat Nov 04 21:35:40 2017 >>> print(time.localtime()) #本地时区的struct_time time.struct_time(tm_year=2017, tm_mon=11, tm_mday=4, tm_hour=21, tm_min=34, tm_sec=40, tm_wday=5, tm_yday=308, tm_isdst=0) >>> print(time.gmtime()) #UTC时区的struct_time time.struct_time(tm_year=2017, tm_mon=11, tm_mday=4, tm_hour=13, tm_min=34, tm_sec=57, tm_wday=5, tm_yday=308, tm_isdst=0)
%y 去掉世纪的年份表示(00 - 99) %Y 完整的年份表示(0000 - 9999) %m 月份(01 - 12) %d 一个月中的第几天(01 - 31) %H 24小时制小时数(00 - 23) %I 12小时制小时数(01 - 12) %M 分钟数(00 - 59) %S 秒(00 - 59) %a 本地(locale)简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示 %j 一年中的第几天(001 - 366) %p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00 - 53)星期天为星期的开始 %w 一个星期中的第几天(0 - 6),星期天为星期的开始 %W 和%U基本相同,不同的是%W是以星期一为一个星期的开始 %x 本地相应的日期表示 %X 本地相应的时间表示 %Z 当前时区的名称(如果不存在为空字符) %% %号本身
其中计算机认识的时间只能是'时间戳'格式,而程序员可处理的或者说人类能看懂的时间有: '格式化的时间字符串','结构化的时间' ,于是有了下图的转换关系
>>> import time #-------------------------------------按图1转换时间------------------------------------------# # localtime([secs]):将一个时间戳转换为当前时区(UTC+8)的struct_time。secs参数未提供,则以当前时间为准。 >>> time.localtime() time.struct_time(tm_year=2017, tm_mon=11, tm_mday=4, tm_hour=21, tm_min=57, tm_sec=41, tm_wday=5, tm_yday=308, tm_isdst=0) >>> x = time.localtime(1509802396.6130548) >>> print(x) time.struct_time(tm_year=2017, tm_mon=11, tm_mday=4, tm_hour=21, tm_min=33, tm_sec=16, tm_wday=5, tm_yday=308, tm_isdst=0) >>> print(x.tm_year) 2017 >>> print(x.tm_yday) 308 # gmtime([secs]) 和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。 # mktime(t) : 将一个struct_time转化为时间戳。 >>> print(time.mktime(time.localtime())) 1509803970.0 # strftime(format[, t]) : 把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。 如果t未指定,将传入time.localtime()。如果元组中任何一个元素越界,ValueError的错误将会被抛出。 >>> print(time.strftime("%Y-%m-%d %X", time.localtime())) 2017-11-04 22:00:32 >>> print(time.strftime("%X %Y-%m-%d", time.localtime())) 22:00:32 2017-11-04 # time.strptime(string[, format]):把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。 >>> print(time.strptime('2017-11-04 22:00:32', '%Y-%m-%d %X')) time.struct_time(tm_year=2017, tm_mon=11, tm_mday=4, tm_hour=22, tm_min=0, tm_sec=32, tm_wday=5, tm_yday=308, tm_isdst=-1) #在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。
>>> import time #将格式字符串转换为时间戳 >>> string_to_struct = time.strptime("2017-10-30 14:48:44","%Y-%m-%d %H:%M:%S") #将 日期字符串 转成 struct时间对象格式 >>> print(string_to_struct) time.struct_time(tm_year=2017, tm_mon=10, tm_mday=30, tm_hour=14, tm_min=48, tm_sec=44, tm_wday=0, tm_yday=303, tm_isdst=-1) >>> struct_to_stamp = time.mktime(string_to_struct) #将struct时间对象格式转成时间戳 >>> print(struct_to_stamp) 1509346124.0 或者一步到位 >>> print(time.mktime(time.strptime("2017-10-30 14:48:44","%Y-%m-%d %H:%M:%S")) ) 1509346124.0 #将时间戳转换为格式字符串 >>> print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(1509346124.0)) ) 2017-10-30 14:48:44
>>> import time #-----------------------------------------按图2转换时间-------------------------------------------# # asctime([t]) : 把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。如果没有参数,将会将time.localtime()作为参数传入。 >>> print(time.asctime()) Sat Nov 4 22:19:37 2017 # ctime([secs]) : 把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。
它的作用相当于time.asctime(time.localtime(secs))。 >>> print(time.ctime()) Sat Nov 4 22:19:56 2017 >>> print(time.ctime(time.time())) Sat Nov 4 22:20:35 2017 #---------------------------------------其它用法---------------------------# # sleep(secs):线程推迟指定的时间运行,单位为秒。
#时间加减 >>> import datetime >>> print(datetime.datetime.now()) #返回当前时间 2017-11-04 22:28:16.976757 >>> print(datetime.date.fromtimestamp(time.time()) ) # 时间戳直接转成日期格式 2017-11-04 >>> print(datetime.datetime.now() ) 2017-11-04 22:29:12.067908 >>> print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天 2017-11-07 22:29:24.544621 >>> print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天 2017-11-01 22:29:38.412414 >>> print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时 2017-11-05 01:29:50.667115 >>> print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分 2017-11-04 23:00:03.260836 >>> c_time = datetime.datetime.now() >>> print(c_time.replace(minute=3,hour=2)) #时间替换 2017-11-04 02:03:37.749808
二 random
随机数
>>> import random >>> print(random.random()) #(0,1)----float 大于0且小于1之间的小数。也可以指定区间,看下一个 0.4389206383156363 >>> print(random.uniform(1,3)) #大于1小于3的小数 1.8623602068930234 >>> print(random.randint(1,3)) #[1,3] 大于等于1且小于等于3之间的整数 1 >>> print(random.randrange(1,3)) #[1,3) 大于等于1且小于3之间的整数 2 >>> print(random.choice([1,'23',[4,5]])) #1或者23或者[4,5] 23 >>> print(random.sample([1,'23',[4,5]],2)) #列表元素任意2个组合 ['23', 1] >>> item=[1,3,5,7,9] >>> random.shuffle(item) #打乱item的顺序,相当于"洗牌" >>> print(item) [7, 3, 1, 5, 9]
>>> import random >>> def make_code(n): res = '' for i in range(n): s1 = chr(random.randint(65,90)) s2 = str(random.randint(0,9)) res += random.choice([s1,s2]) return res >>> print(make_code(9)) 5Z126T88M
三 OS模块
OS模块是于操作系统交互的一个接口
import 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下为" ",Linux下为" " 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所指向的文件或者目录的最后修改时间 os.path.getsize(path) 返回path的大小
更多猛击这里
>>> import os # 在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。 >>> os.path.normcase('c:/windows\system32\') 'c:\windows\system32\' # 规范化路径,如..和/ >>> os.path.normpath('c://windows\System32\../Temp/') 'c:\windows\Temp' >>> a='/Users/jieli/test1/\a1/\\aa.py/../..' >>> print(os.path.normpath(a)) Usersjieli est1
os路径处理 #方式一:推荐使用 import os,sys >>> possible_topdir = os.path.normpath(os.path.join( os.path.abspath(os.__file__), os.pardir, os.pardir, os.pardir )) >>> sys.path.insert(0,possible_topdir) #方式二:不推荐使用 import os >>> os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(os.__file__)))) 'C:\Users\Administrator\AppData\Local\Programs\Python'
四 sys模块
1 sys.argv # 命令行参数List,第一个元素是程序本身路径 2 sys.exit(n) # 退出程序,正常退出时exit(0) 3 sys.version # 获取Python解释程序的版本信息 4 sys.maxint # 最大的Int值 5 sys.path # 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 6 sys.platform # 返回操作系统平台名称 7 sys.stdout.write('please:') 8 val = sys.stdin.readline()[:-1]
#=========知识储备========== #进度条的效果 [# ] [## ] [### ] [#### ] #指定宽度 print('[%-15s]' %'#') print('[%-15s]' %'##') print('[%-15s]' %'###') print('[%-15s]' %'####') #打印% print('%s%%' %(100)) #第二个%号代表取消第一个%的特殊意义 #可传参来控制宽度 print('[%%-%ds]' %50) #[%-50s] print(('[%%-%ds]' %50) %'#') print(('[%%-%ds]' %50) %'##') print(('[%%-%ds]' %50) %'###') #=========实现打印进度条函数========== import sys import time def progress(percent,width=50): if percent >= 1: percent=1 show_str=('[%%-%ds]' %width) %(int(width*percent)*'#') print(' %s %d%%' %(show_str,int(100*percent)),file=sys.stdout,flush=True,end='') #=========应用========== data_size=1025 recv_size=0 while recv_size < data_size: time.sleep(0.1) #模拟数据的传输延迟 recv_size+=1024 #每次收1024 percent=recv_size/data_size #接收的比例 progress(percent,width=70) #进度条的宽度70
五 shutil模块
高级的文件、文件夹、压缩包处理模块。包括复制、移动、重命名、删除等等。
shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中
>>> import shutil >>> shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
shutil.copyfile(src, dst)
拷贝文件
>>> shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在,一般不用
shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变。
>>> shutil.copymode('f1.log', 'f2.log') #目标文件必须存在,一般不用
shutil.copystat(src, dst)
仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
>>> shutil.copystat('f1.log', 'f2.log') #目标文件必须存在,一般不用
shutil.copy(src, dst)
拷贝文件和权限
>>> import shutil >>> shutil.copy('f1.log', 'f2.log')
shutil.copy2(src, dst)
拷贝文件和状态信息
>>> import shutil >>> shutil.copy2('f1.log', 'f2.log')
shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹
>>> import shutil >>> shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,
注意对folder2目录父级目录要有可写权限,ignore的意思是排除
>>> import shutil >>> shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) ''' 通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件 '''
shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件
>>> import shutil >>> shutil.rmtree('folder1')
shutil.move(src, dst)
递归的去移动文件,它类似mv命令,其实就是重命名。
>>> import shutil >>> shutil.move('folder1', 'folder3')
shutil.make_archive(base_name,format,...)
创建压缩包并返回文件路径,例如:zip、tar
- base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如:data_bak =>保存至当前路径
如:/tmp/data_bak =>保存至/tmp/test/
- format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
- root_dir: 要压缩的文件夹路径(默认当前目录)
- owner: 用户,默认当前用户
- group: 组,默认当前组
- logger: 用于记录日志,通常是logging.Logger对象
#将 /data 下的文件打包放置当前程序目录 >>> import shutil >>> shutil.make_archive('data_bak','tar',root_dir='/data') '/root/data_bak.tar' #将 /data下的文件打包放置 /tmp/ 目录 >>> shutil.make_archive('/tmp/data_bak','tar',root_dir='/data') '/tmp/data_bak.tar'
shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
import zipfile # 压缩 z = zipfile.ZipFile('laxi.zip', 'w') z.write('a.log') z.write('data.data') z.close() # 解压 z = zipfile.ZipFile('laxi.zip', 'r') z.extractall(path='.') z.close()
import tarfile # 压缩 >>> t=tarfile.open('/tmp/egon.tar','w') >>> t.add('/test1/a.py',arcname='a.bak') >>> t.add('/test1/b.py',arcname='b.bak') >>> t.close() # 解压 >>> t=tarfile.open('/tmp/egon.tar','r') >>> t.extractall('/egon') >>> t.close()
六 json & pickle模块
用于序列化的两个模块
- json,用于字符串和python数据类型间进行转换
- pickle,用于python特有的类型和python的数据类型间进行转换
json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
>>> import pickle >>> data = {'k1':123,'k2':'Hello'} # pickle.dumps 将数据通过特殊的形式装换为只有python语言认识的字符串 >>> p_str = pickle.dumps(data) >>> print(p_str) b'x80x03}qx00(Xx02x00x00x00k1qx01K{Xx02x00x00x00k2qx02Xx05x00x00x00Helloqx03u.' # pickle.dump 将数据通过特殊的形式装换为只有python语言认识的字符串,并写入文件 >>> with open(r'D: esult.pk','wb') as fp: pickle.dump(data,fp) #读取pickle文件 >>> with open(r'D: esult.pk','rb') as fp: pickle.load(fp) {'k2': 'Hello', 'k1': 123} >>> import json # json.dumps 将数据通过特殊的形式转换为所有程序语言都认识的字符串 >>> j_str = json.dumps(data) >>> print(j_str) {"k2": "Hello", "k1": 123} # json.dumps 将数据通过特殊的形式转换为所有程序语言都认识的字符串,并写入文件 >>> with open(r'D: esult.json','w') as fp: json.dump(data,fp) #读取json文件 >>> with open(r'D: esult.json','r') as fp: json.load(fp) {'k2': 'Hello', 'k1': 123}
七 shelve模块
shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式,并且可以多次 dump 和 load
>>> import shelve >>> import datetime #持久化数据 >>> info = {'name': 'bigberg', 'age': 22} >>> name = ['Apoll', 'Zous', 'Luna'] >>> t = datetime.datetime.now() >>> with shelve.open('/tmp/shelve.txt') as f: #执行代码后会生成3个文件:shelve.txt.bak、shelve.txt.dat、shelve.txt.dir。 ... f['name'] = name #持久化列表 ... f['info'] = info #持久化字典 ... f['time'] = t #持久化时间类型 ... #读取数据 >>> with shelve.open('shelve.txt') as f: #打开文件 ... print(f.get('name')) #使用get获取数据 ... print(f.get('info')) ... print(f.get('time')) ... ['Apoll', 'Zous', 'Luna'] {'name': 'bigberg', 'age': 22} 2017-11-01 16:07:29.261414
八 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协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:
print(root.iter('year')) #全文搜索 print(root.find('country')) #在root的子节点找,只找一个 print(root.findall('country')) #在root的子节点找,找所有
import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() print(root.tag) #遍历xml文档 for child in root: print('========>',child.tag,child.attrib,child.attrib['name']) for i in child: print(i.tag,i.attrib,i.text) #只遍历year 节点 for node in root.iter('year'): print(node.tag,node.text) #--------------------------------------- import xml.etree.ElementTree 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') node.set('version','1.0') tree.write('test.xml') #删除node for country in root.findall('country'): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write('output.xml')
#在country内添加(append)节点year2 import xml.etree.ElementTree as ET tree = ET.parse("a.xml") root=tree.getroot() for country in root.findall('country'): for year in country.findall('year'): if int(year.text) > 2000: year2=ET.Element('year2') year2.text='新年' year2.attrib={'update':'yes'} country.append(year2) #往country节点下添加子节点 tree.write('a.xml.swap')
自己创建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", encoding="utf-8",xml_declaration=True) ET.dump(new_xml) #打印生成的格式
九 configparser模块
用于生成和修改常见配置文档。
一个典型的Mysql配置文件如下:
[mysqld] port = 3306 socket = /var/lib/mysql/mysql.sock key_buffer = 384M myisam_sort_buffer_size = 64M thread_cache_size = 8 query_cache_size = 32M max_connections=500 thread_concurrency = 8 [client] user = root password = 123456 port = 3306 socket = /var/lib/mysql/mysql.sock
读取
>>> import configparser >>> config=configparser.ConfigParser() >>> config.read('my.cnf') ['my.cnf'] #查看所有的标题 >>> res=config.sections() >>> print(res) ['mysqld', 'client'] #判断是否存在某个标题 >>> 'mysqld' in config True >>> print(config.has_section('mysqld')) #同上一个 True #判断标题mysqld下是否有user >>> print(config.has_option('mysqld','user')) False #查看标题client下所有key=value的key >>> options=config.options('client') >>> print(options) ['user', 'password', 'port', 'socket'] >>> for key in config['client']:print(key) #同上一个 ... user password port socket #查看标题client下所有key=value的(key,value)格式 >>> item_list=config.items('client') >>> print(item_list) [('user', 'root'), ('password', '123456'), ('port', '3306'), ('socket', '/var/lib/mysql/mysql.sock')] #查看标题client下user的值=>字符串格式 >>> val=config.get('client','user') >>> print(val) root >>> config['client']['user'] #同上一个 'root' #查看标题client下port的值=>整数格式 >>> val1=config.getint('client','port') >>> print(val1) 3306 #查看标题mysqld下mysql_update的值=>布尔值格式 val2=config.getboolean('mysqld','mysql_update') print(val2) #查看标题mysqld下max_connections的值=>浮点型格式 val3=config.getfloat('mysqld','max_connections') print(val3)
改写
>>> import configparser >>> config=configparser.ConfigParser() >>> config.read('my.cnf',encoding='utf-8') ['my.cnf'] #删除整个标题client >>> config.remove_section('client') True 删除标题mysqld下的key_buffer和thread_cache_size >>> config.remove_option('mysqld','key_buffer') True >>> config.remove_option('mysqld','thread_cache_size') True #添加一个标题 >>> config.add_section('mysql') #在标题mysqld下添加read_buffer_size=2M,thread_concurrency=8的配置 >>> config.set('mysqld','read_buffer_size','2M') >>> config.set('mysqld','thread_concurrency','8') #最后将修改的内容写入文件,完成最终的修改 >>> config.write(open('my.cnf','w'))
>>> 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 = 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) ...
十 hashlib模块
hash:一种算法 ,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
三个特点:
- 内容相同则hash运算结果相同,内容稍微改变则hash值则变
- 不可逆推
- 相同算法:无论校验多长的数据,得到的哈希值长度固定。
>>> import hashlib >>> m = hashlib.md5() # m = hashlib.sha256() >>> m.update('hello'.encode('utf-8')) >>> print(m.digest()) #2进制格式hash b']A@*xbcK*vxb9qx9dx91x10x17xc5x92' >>> print(m.hexdigest()) #16进制格式hash 5d41402abc4b2a76b9719d911017c592 >>> m.update('alvin'.encode('utf8')) >>> print(m.hexdigest()) 92a7e713c30abbb0319fa07da2a5c4af >>> m2=hashlib.md5() >>> m2.update('helloalvin'.encode('utf8')) >>> print(m2.hexdigest()) 92a7e713c30abbb0319fa07da2a5c4af ''' 注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样,但是update多次为校验大文件提供了可能。 '''
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
>>> import hashlib ######## 256 ######### >>> hash = hashlib.sha256('898oaFs09f'.encode('utf8')) >>> hash.update('alvin'.encode('utf8')) >>> print (hash.hexdigest()) e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7
import hashlib passwds=[ 'alex3714', 'alex1313', 'alex94139413', 'alex123456', '123456alex', 'a123lex', ] def make_passwd_dic(passwds): dic={} for passwd in passwds: m=hashlib.md5() m.update(passwd.encode('utf-8')) dic[passwd]=m.hexdigest() return dic def break_code(cryptograph,passwd_dic): for k,v in passwd_dic.items(): if v == cryptograph: print('密码是===>