No.008-Python-学习之路-Day5-random|os|sys|shutil|shelve|xml|PyYAML|ConfigParser|hashlib|RE
Random模块
模块主要函数
>>> import random >>> random.random() # 0-1内的随机浮点数 0.06052892434757606 >>> random.uniform(1,3) # 1-3范围内的随机浮点数 >>> random.uniform(3,1) # 3-1也是可以的 1.0158647412645498 >>> random.randint(1,3) # 1-3范围内的随机整数 1 >>> random.randrange(0,100,2) # 类似于从rang()取出一个值 32 >>> random.choice('学习Python') # 从一个序列中获取一个随机元素 '习' >>> random.choice(['every','cloud','has', 'a', 'silver','lining']) 'a' >>> s =[1,2,5,123123,132,1123] #对一个序列进行随机排序并返回 >>> random.shuffle(s) >>> s [1, 123123, 132, 5, 2, 1123] >>> l = [1,2,3,4,5,6,7] # 对一个序列进行随机的切片 >>> random.sample(l, 4) [1, 4, 6, 3]
综合举例-验证码生成
def check_code(num): ''' create a [num] long check code by random() :param num:how long check code will be created :return:random check code in <range 0-9,a-z,A-Z> ''' import random code = '' if num and str(num).isdigit(): # 生成字符串的长度 for i in range(int(num)): # 随机选择类型 choice = random.randrange(3) if choice == 0: # 随机的数字 code += str(random.randint(0,9)) elif choice == 1: # 随机的大写字母 code += chr(random.randint(65, 90)) elif choice == 2: # 随机的小写字母 code += chr(random.randint(97, 122)) return code else: return False print(check_code("aa")) print(check_code(6))
os模块
os 模块提供了非常丰富的方法用来处理文件和目录,常用的方法如下:
import os #目录相关操作
os.getcwd() # 获取当前目录
os.chdir(dirname) # 切换工作目录到指定目录
os.mkdir(dirname) # 非递归创建目录 os.rmdir(dirname) # 非递归删除目录 os.makedirs(dirname) # 递归创建目录 os.removedirs(dirname) # 递归删除目录 os.listdir(dirname) # 列出目录下所有内容,list对象 os.curdir # 返回当前目录 os.pardir # 返回父级目录 os.remove(path) # 删除文件 os.rename('oldname', 'newname') # 重命名文件 os.stat(path) # 获取文件信息 # 系统相关信息获取 os.sep # 获取路径分隔符,win的"\\",linux的"/" os.linesep # 获取换行符 os.pathsep # 获取path的分隔符,win的";",linux的":" os.environ # 获取环境变量 os.name # 获取系统的类型,win是ns,linux是posix # 针对系统执行命令 os.system("command") # 执行命令,返回0,1成功或失败
os.popen("command") # 执行命令,将命令获取的值存为一个文件对象,可使用read (status, output) = commands.getstatusoutput("command") # 如果想同时获得以上两种结果,可以使用该条命令;
# 路径的相关信息的获取 os.path.abspath(path) # 根据路径生成绝对路径 os.path.split(path) # 将路径分割为一个tuple(dir, file),不考虑路径是否存在 os.path.dirname(path) # 返回dir,不考虑路径是否存在 os.path.basename(path) # 返回文件名,不考虑路径是否存在 os.path.exists(path) # 判断是否存在 os.path.isabs(path) # 判断是不是绝对路径 os.path.isfile(path) # 判断是不是文件 os.path.isdir(path) # 判断是不是目录 os.path.join(path1, path2) # 将两个目录合并成一个 os.path.getatime(path) # 获取文件的存取时间 os.path.getmtime(path) # 获取文件的修改时间
sys模块
Python中的sys模块提供访问<由解释器使用或维护的变量>的接口,并提供一些函数用来和解释器进行交互,操控Python的运行时的系统环境;
sys.argv
# test.py import sys print(sys.argv) # 命令行传参数使用,生成一个含有脚本名及相应参数的list # 运行 >python test.py 1 2 3 4 5 ['test.py', '1', '2', '3', '4', '5']
sys.exit([arg])
# 程序执行的返回值,返回并结束程序 argv = sys.argv ip = os.popen("dig +time=3 +short {} @{}".format(argv[1],argv[2])).read().strip() now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) if argv[1] == "xxx.xx.com": if ip == "172.20.xx.xx": print("1") # with open("/tmp/uad_dns_wrong.log", "a") as f: # f.write("[{}] {}\n".format(now, ip)) sys.exit(1) else: print("0") with open("/tmp/uad_dns_wrong.log", 'a') as f: f.write("[{}] {}\n".format(now, ip)) sys.exit(0) else: print("2") sys.exit(2)
sys.stdin() sys.stdout(), stderr()
# stdin str1 = sys.stdin.readline() # 类似于input,会读最后的换行符; str1 = sys.stdin.readline().strip() # 去除方法1 str1 = sys.stdin.readline()[:-1] # 去除方法2 # stdout 在python中调用print()时,事实上调用了sys.stdout.write(obj+'\n') # stderr # 错误输出内容,待续
其他一些方法属性
sys.version # 获取Python解释器程序的版本信息 sys.maxint # 最大的int值 sys.path # 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量值 sys.platform # 返回操作系统平台名称
进度条程序举例
import sys import math import time def bar(portion, total): # 参数,当前,总共 part = total / 50 count = math.ceil(portion/part) # sys.stdout.write('\r') # 从行开头从写 sys.stdout.write(('[%-50s]%.2f%%' % (('#' * count), portion / total * 100))) # %-*s 左对齐,宽度50,%.2f浮点数2位 sys.stdout.flush() # 缓存刷新 if portion >= total: sys.stdout.write('\n') return True portion = 0 total = 10000 while True: portion += 100 time.sleep(0.1) end = bar(portion, total) if end:break print("OK")
shutil模块
高级的文件、文件夹、压缩包处理模块,-->减少调用shell命令的方式
shutil.copyfileobj(fsrc, fdst, [,length])
# 将文件内容拷贝到另外一个文件,可以部分 # 参数需为文件对象 import shutil f1 = open("本节课笔记.txt", 'r', encoding="utf-8") f2 = open("本节课笔记2.txt", 'w', encoding="utf-8") shutil.copyfileobj(f1, f2)
shutil.copyfile(fsrc, fdst, [,length])
# 将文件内容拷贝到另外一个文件,可以部分 # 参数需为文件名 import shutil shutil.copyfile("本节课笔记.txt", "本节课笔记3.txt")
shutil.copymode(fsrc, fdst)
# 将文件的权限copy到另外一个文件,仅权限至目标文件,用户,组及内容不copy # 参数为文件名 import shutil shutil.copymode("本节课笔记.txt", "本节课笔记3.txt")
shutil.copystat(fsrc, fdst)
# 将文件关联的权限和日期copy到另外一个文件 # 参数为文件名 import shutil shutil.copymode("本节课笔记.txt", "本节课笔记3.txt")
shutil.copy(fsrc, fdst)
# 拷贝文件和权限 # 相当于 copyfile() copymode()
shutil.copy(fsrc, fdst)
# 拷贝文件和权限和一些属性 # 相当于 copyfile() copystat()
shutil.copytree(fsrc, fdst)
# 递归copy文件 # 即可以copy目录
shutil.rmtree(fsrc, fdst)
# 删除目录
shutil.move(fsrc, fdst)
# 移动文件
shutil.make_archive(base_name, format,...)
# 创建压缩包并返回文件路径,例如:zip、tar # base_name:压缩包的文件名,也可以是压缩包的路径; # format:压缩包类型,zip, tar, bztar, gztar # root_dir:要压缩的文件夹路径(默认当前目录) # owner:用户, 默认当前用户 # group:组,默认当前组 # logger:用于记录日志,通常是logging.Logger对象
# 其实是使用
import shutil shutil.make_archive(r"D:\my_python", "zip", r"D:\资料存放\PythonObjects")
# make_archive调用了zipfile及tarfile完成压缩 # make_archive主要针对目录,如果有部分文件压缩可以直接使用压缩模块 import zipfile import tarfile # tar类似于zipfile,其中write改为add之类的 # 压缩 z = zipfile.ZipFile("ziptest.zip", "w") z.write("本节课笔记.txt") z.write("本节课笔记2.txt") z.write("本节课笔记3.txt") z.close() # 解压 z = zipfile.ZipFile("ziptest.zip", "r") z.extractall() z.close()
shelve
简述
Shelve是对象持久化保存方法,将对象保存到文件里面,缺省(即默认)的数据存储文件是二进制的;
shelve将对象保存到文件里面,缺省的数据存储文件是二进制的,‘dict-like’对象的调用方式;
anydbm类似于shelve,区别相同于json与pickle,anydbm的key与value必须是字符串,而shelve可以为认证python数据类型;
方法
# 创建或打开一个shelve对象。shelve默认打开方式支持同时读写操作 shelve.open(filename, flag=’c’, protocol=None, writeback=False) #可选参数flag,默认为‘c’,如果数据文件不存在,就创建,允许读写;可以是: ‘r’: 只读;’w’: 可读写; ‘n’: 每次调用open()都重新创建一个空的文件,可读写 # 同步并关闭shelve对象 shelve.close() # 可以使用with语句: with shelve.open('spam') as db: db['eggs'] = 'eggs'
实例-序列化数据
import shelve import time d = shelve.open("shelve_test") # 打开一个文件 class Test(object): def __init__(self, n): self.n = n def show(self): print(self.n) t1 = Test(123) # 类实例化 time1 = time.ctime(time.time()) # 时间格式数据 name = ['Bruce', "Amadeus", "Lee"] # 列表格式数据 d["test"] = name # 格式化列表 d["t1"] = t1 # 格式化类 d["time"] = time1 # 格式化时间 d.close()
实例-反序列数据
import shelve class Test(object): def __init__(self, n): self.n = n def show(self): print(self.n) with shelve.open("shelve_test", flag='r') as d: # 可以使用with方法 t1 = d.get("t1") # 类似于字典的取值方式 time = d["time"] name = d.get("test") t1.show() print(time) print(name)
xml
XML 是各种应用程序之间进行数据传输的常用的工具,目前渐渐为JSON取代,下面是一段XML文本:
<Bruce> <country name="Bang"> <rank updated="yes">5</rank> <year updated="yes">2018</year> <gdppc>5990</gdppc> <neighbor direction="E" name="Austria" /> <old ddd = "aaa">111</old> </country> </Bruce>
XML的获取
import xml.etree.ElementTree as ET tree = ET.parse('xmltest.xml') root = tree.getroot() print(root) # 根的Element对象 print(root.tag) # 根的标签 # 遍历xml文档 for child in root: print(child.tag, child.attrib) print("fengefu".center(50,"-")) for i in child: print(i.tag, i.text, i.attrib) # 标签,内容,属性 # 遍历节点 for node in root.iter('neighbor'): print(node.tag, node.text,node.attrib) # 标签,内容,属性
XML的修改
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") # 添加属性 tree.write("xmltest.xml") # 更新原文件 # 删除 for country in root.findall("country"): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write("xmltest.xml") # 更新原文件
XML的新建
import xml.etree.ElementTree as ET new_xml = ET.Element("namelist") name = ET.SubElement(new_xml, "name", attrib={"enrolled":"yes", "name": "Bruce"}) age = ET.SubElement(name, "age", attrib={"checked":"no"}) sex = ET.SubElement(name, "sex") age.text = '33' name2 = ET.SubElement(new_xml, "name", attrib={"enrolled":"no"}) name2.text = "Amadeus" 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) # 打印生成的格式 tree = ET.parse("test.xml") print(tree) root = tree.getroot() print(root.tag) for node in root.iter("name"): print(node.tag, node.text, node.attrib)
PyYAML
是一个三方库,用于生成及读取配置文件,官方文档:https://pyyaml.org/wiki/PyYAMLDocumentation;
pyyaml模块在python中用于处理yaml格式数据,主要使用yaml.safe_dump()、yaml.safe_load()函数将python值和yaml格式数据相互转换;
如果想对一个yaml文件中的多块yaml数据进行转换操作,则可以使用yaml.safe_dump_all()、yaml.safe_load_all()函数;
ConfigParser
用于生成和修改常见配置文档,当前模块的名称在python3.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 = config['topsecret.server.com'] topsecret["Host Port"] = '50022' topsecret["ForwardX11"] = 'no' config['DEFAULT']['ForwardX11'] = 'yes' # 增加字典元素 with open("example.ini", 'w') as configfile: config.write(configfile)
[DEFAULT] serveraliveinterval = 45 compression = yes compressionlevel = 9 forwardx11 = yes [bitbucket.org] user = hg [topsecret.server.com] host port = 50022 forwardx11 = no
读取配置文件
>>> import configparser # 导入模块 >>> config = configparser.ConfigParser() # 初始化对象 >>> config.read('example.ini') # 读取文件 >>> config.sections() # 获取group <DEFAULT的默认不打印> ['bitbucket.org', 'topsecret.server.com'] >>> config.options('topsecret.server.com') # 获取option ['host port', 'forwardx11', 'serveraliveinterval', 'compression', 'compressionlevel'] >>> config.items('topsecret.server.com') # 获取items<key与value的元祖> [('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'no'), ('host port', '50022')] >>> config.defaults()['compression'] # 获取值,DEFAULT下的值,要这样获取 'yes' >>> config['bitbucket.org']['user'] # 获取值,类似于字典 'hg' >>> config.get('topsecret.server.com', 'host port') # 获取值的方式二 '50022' >>> config.getint('topsecret.server.com', 'host port') # 获取值的方式二 50022
修改配置文件
import configparser config = configparser.ConfigParser() print(config.sections()) config.read('example.ini') # 删除section sec = config.remove_section('bitbucket.org') # 返回成功<TRUE>or失败<FALSE> config.write(open('example.ini', 'w')) # 写入文件 # 删除option config.remove_option('DEFAULT', 'compressionlevel') config.write(open('example.ini', 'w')) # 添加group sec = config.has_section('bitbucket1.org') if not sec: sec = config.add_section('bitbucket1.org') config.write(open('example.ini', 'w')) # 设置option sec = config.has_option('bitbucket1.org', 'user') if not sec: sec = config.set('bitbucket1.org', 'user', 'Amadeus') config.write(open('example.ini', 'w'))
hashlib
用于加密相关的操作,3.x内代替了MD5模块和sha模块,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法<这些算法都是基于hash的>;
hash在字典中建立映射关系,目的是为了提高查询速度,具体点这里
相同的内容hash的值是相同的;
正常的加密操作
m = hashlib.md5() # 生成一个对象 m.update("天Hello".encode()) # 需要加密的内容 print(m.hexdigest()) # 直接打印16进制字符串 print(m.digest()) # 打印二进制 m.update(b"It's me") # 叠加的 print(m.hexdigest())
使用hmac进行二次加密
import hmac h = hmac.new("你么".encode("utf-8"), "你好".encode('utf-8')) print(h.digest()) print(h.hexdigest())
re模块
常用正则表达式符号:
'.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) '$' 匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以 '*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a'] '+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb'] '?' 匹配前一个字符1次或0次 '{m}' 匹配前一个字符m次 '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb'] '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC' '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c '\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的 '\Z' 匹配字符结尾,同$ '\d' 匹配数字0-9 '\D' 匹配非数字 '\w' 匹配[A-Za-z0-9] '\W' 匹配非[A-Za-z0-9] 's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t' '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city")
结果{'province': '3714', 'city': '81', 'birthday': '1993'}
贪婪匹配与最小匹配
re模块默认为贪婪匹配,即匹配最长的,可以使用如下方式匹配最短的;
>>> re.search("a.*?c", "abcabc") # 使用最小匹配 <re.Match object; span=(0, 3), match='abc'> >>> re.search("a.*c", "abcabc") # 默认贪婪匹配 <re.Match object; span=(0, 6), match='abcabc'>
re模块匹配方法
# re.match意为从头开始匹配,所以自带‘^’字符,\A同^ \Z同$,调用group方法取得值 >>> re.match("r.*e$","Bruce Amadeus Lee") # r不是在字符串头,所以未匹配到 >>> re.match("B.*e$","Bruce Amadeus Lee") # B在开头匹配到 <re.Match object; span=(0, 17), match='Bruce Amadeus Lee'> >>> re.match("^B.*e$","Bruce Amadeus Lee") # 等价于上面表达式, <re.Match object; span=(0, 17), match='Bruce Amadeus Lee'> # re.search在字符串内取一个匹配到的值<仅取回一个值>,调用group方法取得之 >>> re.search("r.*e","Bruce Amadeus Lee") <re.Match object; span=(1, 17), match='ruce Amadeus Lee'> >>> re.search("(a.*?c){2}", "abcabc") # 分组 <re.Match object; span=(0, 6), match='abcabc'> # re.findall返回所有的匹配到的值以list形式返回,re.finditer返回的是迭代器 >>> re.findall("u.*?e","Bruce Amadeus Lee") ['uce', 'us Le'] >>> re.findall("u.*?e|r.*?u","Bruce Amadeus Lee") ['ru', 'us Le'] # re.split以正则表达式匹配字符为分隔符 >>> re.split("\d+", "ab123cd131ef1124hk1123aa") ['ab', 'cd', 'ef', 'hk', 'aa'] # re.sub匹配到的值替换 >>> re.sub("\d+","|", "ab123cd131ef1124hk1123aa") 'ab|cd|ef|hk|aa' >>> re.sub("\d+","|", "ab123cd131ef1124hk1123aa", count=2) 'ab|cd|ef1124hk1123aa' #注1: 若匹配成功,match()/search()返回的是Match对象,finditer()返回的也是Match对象的迭代器,获取匹配结果需要调用Match对象的group()、groups或group(index)方法。
#注2: 匹配中的flag的设置:
flags=re.I<OGMPRECASE> 忽略大小写
flags=re.M<MULTLINE> 多行模式,使用本标志后,‘^’和‘$’匹配行首和行尾时,会增加换行符之前和之后的位置;
flags=re.S<DOTALL> 使 “.” 特殊字符完全匹配任何字符,包括换行;没有这个标志, “.” 匹配除了换行符外的任何字符。
re分组匹配
>>> re.search("(?P<tel>\d+)(?P<name>[a-bA-Z]+)", '17752113231Bruce').groupdict() {'tel': '17752113231', 'name': 'B'} >>> re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") {'province': '3714', 'city': '81', 'birthday': '1993'}
end,参考:
http://blog.sina.com.cn/s/blog_15ab3a6e00102yhdp.html
https://www.cnblogs.com/nyist-xsk/p/7978488.html