##Python之路 Day5 经常使用模块node
####import 导入模块python
1.定义git
相似于函数式编程和面向过程编程,函数式编程则完成一个功能,其余代码用来调用便可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能须要多个函数才能完成(函数又能够在不一样的.py文件中),多个.py 文件组成的代码集合就称为模块,是为了实现某个功能的代码集合。
2.导入模块正则表达式
导入模块其实就是告诉Python解释器去解释那个py文件,导入一个py文件,解释器解释该py文件。导入一个包,解释器解释该包下的 __init__.py 文件。 导入方法: import module from module.xx.xx import xx from module.xx.xx import xx as rename from module.xx.xx import *
3.模块的分类算法
模块有time,datetime表示方式有(1)时间戳,(2)格式化时间字符串,(3)元组(struct_time)共九个元素。shell
时间戳express
>>> time.time() 1550499641.1268253 #打印从19700101 8:00:00到当前时间所经历的秒数 >>> time.mktime(time.strptime("2018-11-08 15:32:02","%Y-%m-%d %X")) 1541662322.0 #将当前时间转为时间戳
格式化时间字符串编程
>>> time.ctime(time.time()) 'Mon Feb 18 22:24:59 2019' #接收的参数是字符串 >>> time.asctime(time.localtime()) 'Mon Feb 18 22:25:02 2019' #接收的参数是元组 >>> print(datetime.datetime.now()) 2019-02-18 22:26:41.758610 >>> time.strftime('%X %Y-%m-%d',time.localtime()) '22:33:20 2019-02-18' #根据time.localtime()来自定义时间 >>> print(time.strptime("2018-11-08 15:32:02","%Y-%m-%d %X")) time.struct_time(tm_year=2018, tm_mon=11, tm_mday=8, tm_hour=15, tm_min=32, tm_sec=2, tm_wday=3, tm_yday=312, tm_isdst=-1) #将'2018-11-08 15:32:02'转为time.localtime()格式,#先后格式须要一一对应可是顺序不须要。
元组(struct_time)bash
>>> time.gmtime() #UTC标准时间 time.struct_time(tm_year=2019, tm_mon=2, tm_mday=18, tm_hour=14, tm_min=30, tm_sec=32, tm_wday=0, tm_yday=49, tm_isdst=0) >>> time.localtime() #当前时间 time.struct_time(tm_year=2019, tm_mon=2, tm_mday=18, tm_hour=22, tm_min=30, tm_sec=36, tm_wday=0, tm_yday=49, tm_isdst=0)
获取过去或将来时间dom
>>> print(datetime.datetime.now() + datetime.timedelta(3)) 2019-02-21 22:37:31.583559 #三天后时间 >>> print(datetime.datetime.now() + datetime.timedelta(hours=3)) 2019-02-19 01:38:06.303301 #三小时后时间 >>> print(datetime.datetime.now() + datetime.timedelta(hours=-3)) 2019-02-18 19:38:28.503632 #三小时前时间
替换时间
>>> print(datetime.datetime.now().replace(minute=3,hour=2)) 2019-02-18 02:03:08.503691
import random print(random.random()) ##生成0到一之间随机数 print(random.randint(100,999)) ##生成100到999之间随机数 print random.randrange(1,10) ##生成1到10之间随机数,不包含10 print(random.choice([1,'23',[4,5]])) #从列表中返回其中一个值 print(random.uniform(1,3)) ##大于1小于3的小数,如1.927109612082716 print(random.sample('hello',3)) ##从整体序列或集合中选择多个惟一的随机元素,以列表形式返回。 item=[1,3,5,7,9] random.shuffle(item) ##打乱item的顺序,至关于"洗牌" print(item) import string print(string.ascii_lowercase) ##生成小写字母 print(string.ascii_uppercase) ##生成大写字母 print(string.ascii_letters) ##生成全部字母 print(string.digits) ##生成0-9数字 生成随机验证码: import random,string checkcode = '' road=True for i in range(8): if road: checkcode+=random.choice(string.ascii_letters) road=False else: checkcode += random.choice(string.digits) road=True print(checkcode)
提供对操做系统进行调用的接口
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下为"\t\n",Linux下为"\n" os.pathsep 输出用于分割文件路径的字符串 os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' os.system("bash command") 运行shell命令,直接显示,结果没法赋值给变量 os.popen("bash command") 执行系统命令,能够赋值保存可是须要read读。 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所指向的文件或者目录的最后修改时间
import shutil shutil.copyfile('1.txt','2.txt') 拷贝文件 shutil.copy('1.txt','2.txt') 拷贝文件和权限 shutil.copy2('1.txt','2.txt') 拷贝文件和权限,还有时间等属性。 shutil.copymode('f1.log', 'f2.log') 仅拷贝权限。内容、组、用户均不变,目标文件须要已经存在。 shutil.copystat('f1.log', 'f2.log') 仅拷贝权限和状态信息访问时间等。内容、组、用户均不变,目标文件须要已经存在。 shutil.move('1.txt','2.txt') 移动文件,相同目录下至关与更名 shutil.copytree(src, dst) 拷贝目录 shutil.rmtree(path) 删除目录 压缩目录: shutil.make_archive(base_name, format,...) base_name: 压缩包的文件名,也能够是压缩包的路径。只是文件名时,则保存至当前目录,不然保存至指定路径。 format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar” root_dir: 要压缩的文件夹路径(默认当前目录)压缩文件。 注:默认会给你的压缩包加上后缀名。 shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细: import zipfile #压缩 z=zipfile.ZipFile('test.zip','w') z.write('test.xml') z.write('test1.xml') z.close() #解压出一个文件 z=zipfile.ZipFile('test.zip','r') z.extract(member='test.xml') z.close() #解压出全部文件 z=zipfile.ZipFile('test.zip','r') z.extractall(member='test.xml') z.close() import tarfile #压缩 tar = tarfile.open('your.tar','w') tar.add('test.xml', arcname='test.xml') tar.add('test1.xml', arcname='test1.xml') tar.close() # 解压 tar = tarfile.open('your.tar','r') tar.extractall() # 可设置解压地址 tar.close()
####shelve模块 shelve模块以k,v格式存储数据,能够持久化任何pickle可支持的Python数据类型。
#写入: d=shelve.open('shelve_test') info={'age':22,'j ob':'it'} name=['zyl','syf','test'] d['in']=info d['na']=name d.close() #读取例 d=shelve.open('shelve_test') print(d.get('in ')) 结果:{'age': 22, 'j ob': 'it'}
####xml模块
import xml.etree.ElementTree as ET #读取: tree = ET.parse('xmltest.xml') root=tree.getroot() for i in root: print(i.tag,i.attrib) ##tag是第一层的标签名,attrib是第一层标签名的信息。 for c in i: print(c.tag,c.text,c.attrib) ##打印第二层的标签名,文本数据,标签名的信息。 for node in root.iter('year'): print(node.tag,node.text) ##只打印单个节点信息,就算year在多级目录下也会打印。 #修改: tree = ET.parse('xmltest.xml') root=tree.getroot() for node in root.iter('year'): node.text=str(int(node.text)+1) ##全部标签为year的内容加1 node.set("updated",'yes') ##设置标签属性。 tree.write('xmltest.xml') ##修改完毕后须要在写入到文件 删除某一段: tree = ET.parse('xmltest.xml') root=tree.getroot() for country in root.findall('country'): rank=int(country.find('year').text) if rank == 2012: root.remove(country) #删除年份为2012的节点 tree.write('output.xml') 编写xml文件: new_xml=ET.Element('data') #一级标签 info=ET.SubElement(new_xml,"personinfo",attrib={'enrolled':'yes'}) #二级标签 info2=ET.SubElement(new_xml,"personinfo2",attrib={'a':'666'}) #二级标签 name=ET.SubElement(info,"name") #三级标签 age=ET.SubElement(info,'age') name.text='zyl' #给三级标签设置值 age.text='30' name=ET.SubElement(info2,"name") #三级标签 age=ET.SubElement(info2,'age') name.text='wq' age.text='16' et=ET.ElementTree(new_xml) #生成et对象 et.write('new_xml',encoding="utf-8",xml_declaration=True) #写入到new_xml文件中
####configparser模块 用于生成和修改常见配置文档 生成以下格式:
[Default] a = 1 b = 2 c = 3 forwardx11 = yes [bit] user = hg [topse] port = 5022 forwardx11 = no
若是想用python生成一个这样的文档怎么作呢?
import configparser #编写文件: config=configparser.ConfigParser() config["Default"]={'a':1, 'b':2, 'c':3} config['bit']={} config['bit']['user']='hg' config['topse']={} a=config['topse'] a['port']='5022' a['forwardx11']='no' config['Default']['ForwardX11']='yes' with open('ConfParser.py','w') as configfile: config.write(configfile) #返回节名称列表,不包括[DEFAULT]: import configparser config = configparser.ConfigParser() config.read('example.ini') config.sections() #读取模块下单独的选项: import configparser config = configparser.ConfigParser() config.read('example.ini') config['bitbucket.org']['User'] #读取模块下选项和对应的参数: >>>print(config.items('bit')) [('user', 'hg')] #只读取模块下全部的选项: >>>config.options('bit') ['user'] #删除单个模块: config.remove_section('group1') #添加一个模块: config.add_section('wupeiqi') #给新加的模块添加一个键值对 config.set('wupeiqi','user','zyl') #修改一个选项的值: config.set('group2','k1',11111) #删除一个选项: config.remove_option('group2','age') #注意:全部修改文件的操做都须要冲新写入到一个文件中。 config.write(open('ConfParser.py','w'))
####hashlib模块 用于加密相关的操做,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512,MD5算法
import hashlib #md5: m = hashlib.md5() m.update(b"Hello") ##必须为bytes格式 m.update(b"It's me") ##多个值会组成一个值,至关于b“Hello It's me” print(m.digest()) #2进制格式hash print(m.hexdigest()) #16进制格式hash #sha256: m = hashlib.sha512() m.update(b"Hello") print(m.hexdigest()) #加密中文格式: m = hashlib.sha512() m.update("小朱朱".encode(encoding='utf-8')) print(m.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-zA-Z0-9] '[^]' 排除其中全部字符 '\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' #flags标志位 re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同) 例:re.search("([a-z]+)","aaaAaAC234aaa",flags=re.I) S(DOTALL): 点任意匹配模式,改变'.'的行为,能够匹配到换行符。 例:re.search(".+","aaaAaAC\r\n234aaa",flags=re.S)
1.re.match函数
尝试从字符串的起始位置匹配一个模式,若是不是起始位置匹配成功的话,match()就返回none。 语法:re.match(pattern, string, flags=0) #示例: >>> import re >>> obj = re.match('\d+', '123uuasf') >>> print(obj.group()) 123
2.匹配对象方法
1.group() 匹配的整个表达式的字符串 2.group(1) 第一个匹配的()中的值 3.groupdict() 返回以有别名的组的别名为键、以该组截获的子串为值的字典 例:print(re.search("(?P<zyl>[0-9]{2})(?P<zz>\d+)","1234567").groupdict()) 结果:{'zyl': '12', 'zz': '34567'} 4.start() 返回匹配开始的位置 5.end() 返回匹配结束的位置 6.span() 返回一个元组包含匹配(开始,结束)的位置
3.re.search方法
扫描整个字符串并返回第一个成功的匹配。 #示例1: >>> print(re.search('com','www.baidu.com').group()) com #示例2: >>> line = "Cats are smarter than dogs"; >>> searchobj=re.search(r'(.*re)(.*)(th.*)',line) ##默认贪婪 >>> print(searchobj.group(2)) smarter
4.re.sub方法
##替换字符串中的匹配项。 语法: re.sub(pattern, repl, string, count=0, flags=0) #示例1: >>> s='2017/19/31' >>> print(re.sub('(\d+)/(\d+)/(\d+)',r'\3-\2-\1',s)) 31-19-2017 #示例2: >>> re.sub("[0-9]+",'|',"aaa234aa111sfaf") 'aaa|aa|sfaf' pattern : 正则中的模式字符串。 repl : 替换的字符串,也可为一个函数。 string : 要被查找替换的原始字符串。 count : 模式匹配后替换的最大次数,默认0表示替换全部的匹配。
5.findall
在字符串中找到正则表达式所匹配的全部子串,并返回一个列表,若是没有找到匹配的,则返回空列表.match 和 search 是匹配一次而findall匹配全部。 #示例: >>>print(re.findall('\d+','zul111zyl111')) ['111', '111']
6.split方法
按照可以匹配的子串将字符串分割后返回列表,它的使用形式以下: 语法:re.split(pattern, string[, maxsplit=0, flags=0]) #示例: >>> re.split("[0-9]+","aaa234aa111sfaf") ['aaa', 'aa', 'sfaf'] >>> re.split("([0-9]+)","aaa234aa111sfaf") ['aaa', '234', 'aa', '111', 'sfaf'] #保留分隔符
###每日练习 开发一个简单的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等相似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致代码以下
# Author:ZhuYuLiang import re def format_mark(express): express = express.replace('+-', '-') express = express.replace('-+', '-') express = express.replace('++', '+') express = express.replace('--', '+') express = express.replace('*+', '*') express = express.replace('+*', '*') express = express.replace('+/', '/') express = express.replace('/+', '/') return express def Add_and_Sub(value): expr = value sub_expr = re.search(r"\-?\d+\.?\d*[\+\-]\d+\.?\d*", expr) if not sub_expr: return expr else: sub_expr2 = sub_expr.group() if len(sub_expr2.split('+')) > 1: n1, n2 = sub_expr2.split('+') result = float(n1) + float(n2) else: n1, n2 = sub_expr2.split('-') result = float(n1) - float(n2) re_sub_expr = re.sub(r"\-?\d+\.?\d*[\+\-]\d+\.?\d*", str(result), expr, count=1) bb = Add_and_Sub(str(re_sub_expr)) return bb def Multiplication_and_division(value): expr = value sub_expr = re.search(r"\d+\.?\d*[\/\*]\-?\d+\.?\d*", expr) if not sub_expr: return expr else: sub_expr2 = sub_expr.group() if len(sub_expr2.split('/')) > 1: n1, n2 = sub_expr2.split('/') result = float(n1) / float(n2) elif len(sub_expr2.split('*')) > 1: n1, n2 = sub_expr2.split('*') result = float(n1) * float(n2) else: # 只计算乘除,加减直接pass,放入加减函数执行 pass re_sub_expr = re.sub(r"\d+\.?\d*[/\*]\-?\d+\.?\d*", str(result), expr, count=1) # 反复调用除法 bb = Multiplication_and_division(format_mark(re_sub_expr)) return bb def compute(value): value=Multiplication_and_division(format_mark(value)) value=Add_and_Sub(format_mark(value)) return value def del_brackets(value): sub_expr=re.search('\([^()]+\)',value) if not sub_expr: return value else: sub_expr=sub_expr.group()[1:-1] sub_expr=compute(sub_expr) sub_expr3 = re.sub('(\([\+\-\*\/\.0-9]+\))', str(sub_expr), value, count=1) delkuohao_expr=del_brackets(format_mark(sub_expr3)) return delkuohao_expr if __name__ == '__main__': while True: express=input('>>: ').replace(' ','') print('eval输出值: ',eval(express)) if not express: continue elif express == 'q': exit() elif re.search('[^0-9.+\-*/()]',express): print('\033[31;1m输入错误\033[0m') else: express=del_brackets(express) express2 = compute(format_mark(express)) print('公式输出值: ',express2)