博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python学习- 常用模块与re正则
阅读量:6874 次
发布时间:2019-06-26

本文共 12639 字,大约阅读时间需要 42 分钟。

开发一个简单的python计算器

  1. 实现加减乘除及拓号优先级解析
  2. 用户输入 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 import sys  2 import re  3    4 def welcome_func():  5     """  6     输入判断  7     :param expression: 表达式  8     :return: 返回有效表达式  9     """ 10     welcome_str = "超级计算器" 11     print(welcome_str.center(50,'*'),'\n')  # 输出欢迎界面 12     while True: 13         iput = input("请输入你要计算的表达式[q:退出]:").strip() 14         if iput == 'q':  # 退出计算 15             sys.exit("bye-bye") 16         elif len(iput) == 0: 17             continue 18         else: 19             iput = re.sub('\s*', '', iput)  # 去除空格 20             return iput 21   22 def chengchu(expression): 23     """ 24     乘除运算 25     :param expression: 表达式 26     :return: 返回没有乘除的表达式/最终计算结果 27     """ 28     val = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', expression)  # 匹配乘除号 29     if not val:  # 乘除号不存在,返回输入的表达式 30         return expression 31     data =  re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', expression).group()  # 匹配乘除号 32     if len(data.split('*')) > 1:  # 当可以用乘号分割,证明有乘法运算 33         part1, part2 = data.split('*')  # 以乘号作为分割符 34         value = float(part1) * float(part2)  # 计算乘法 35     else: 36         part1, part2 = data.split('/')  # 用除号分割 37         if float(part2) == 0:  # 如果分母为0,则退出计算 38             sys.exit("计算过程中有被除数为0的存在,计算表达式失败!") 39         value = float(part1) / float(part2)  # 计算除法 40   41     #print("计算:%s=%s:" % (data,value) ) 42     # 获取第一个匹配到的乘除计算结果value,将value放回原表达式 43     s1, s2 = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', expression, 1)  # 分割表达式 44     #print("上一个表达式:",expression) 45     next_expression  = "%s%s%s" % (s1, value, s2)  # 将计算结果替换会表达式 46     #print("下一个表达式%s" % next_expression) 47     return chengchu(next_expression)  # 递归表达式 48   49   50   51 def jiajian(expression): 52     """ 53     加减运算 54     :param expression: 表达式 55     :return: 返回没有加减的表达式/最终计算结果 56     """ 57     expression = expression.replace('+-','-')   # 替换表达式里的所有'+-' 58     expression = expression.replace('--','+')   # 替换表达式里的所有'--' 59     expression = expression.replace('-+','-')   # 替换表达式里的所有'-+' 60     expression = expression.replace('++','+')   # 替换表达式里的所有'++' 61     #print("处理特殊加减后的表达式:",expression) 62     data = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression)   # 匹配加减号 63     if not data:   # 如果不存在加减号,则证明表达式已计算完成,返回最终结果 64         return expression 65     val = re.search('[\-]?\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression).group() 66     if len(val.split('+')) > 1:   # 以加号分割成功,有加法计算 67         part1, part2 = val.split('+') 68         value = float(part1) + float(part2)   # 计算加法 69     elif val.startswith('-'):  # 如果是已'-'开头则需要单独计算 70         part1, part2, part3  = val.split('-') 71         value = -float(part2) - float(part3)  # 计算以负数开头的减法 72     else: 73         part1, part2 = val.split('-') 74         value = float(part1) - float(part2)  # 计算减法 75       76     s1, s2 =  re.split('[\-]?\d+\.*\d*[\+\-]{1}\d+\.*\d*', expression, 1)  # 分割表达式 77     #print("计算%s=%s" % (val,value)) 78     next_expression = "%s%s%s" % (s1, value, s2)   # 将计算后的结果替换回表达式,生成下一个表达式 79     #print("下一个表达式: ",next_expression) 80     return jiajian(next_expression)  # 递归运算表达式 81   82   83 def del_bracket(expression): 84     """ 85     小括号去除运算 86     :param expression: 表达式 87     :return: 88     """ 89     if not re.search(r'\(([^()]+)\)',expression):   # 判断小括号,如果不存在小括号,直接调用乘除,加减计算 90         ret1 = chengchu(expression) 91         ret2 = jiajian(ret1) 92         return ret2   # 返回最终计算结果 93     data = re.search(r'\(([^()]+)\)', expression).group()  # 如果有小括号,匹配出优先级最高的小括号 94     #print("获取表达式",data) 95     data = data.strip('[\(\)]')   # 剔除小括号 96     ret1 = chengchu(data)   # 计算乘除 97     #print("全部乘除计算完后的表达式:",ret1) 98     ret2 = jiajian(ret1)   # 计算加减 99     #print("全部加减计算结果:",ret2)100     part1, replace_str, part2 = re.split(r'\(([^()]+)\)', expression, 1)  # 将小括号计算结果替换回表达式101     expression = '%s%s%s' % (part1, ret2, part2)  # 生成新的表达式102     return del_bracket(expression)  # 递归去小括号103      104  105 if __name__ == "__main__":106     try:107         expression = welcome_func()   # 获取到的表达式108         #expression = "-1+ 3 *(-3*2-2/-2+1)/2"109         #expression = '1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'110         reslut = eval(expression)   # 用eval计算验证111         ret = del_bracket(expression)  # 用函数计算后得出的结果112         reslut = float(reslut)113         ret = float(ret)114         if reslut == ret:   # 将两种方式计算的结果进行比较,如果相等,则计算正确,输出结果115             print("eval计算结果:%s" % reslut)116             print("表达式计算结果:%s" % ret)117         else:   # 两种计算方式的结果不正确,提示异常,并返回两种方式的计算结果118             print("计算结果异常,请重新检查!")119             print("eval计算结果:%s" % reslut)120             print("表达式计算结果:%s" % ret)121     except(SyntaxError,ValueError,TypeError):   # 如果有不合法输出,则抛出错误122         print("输入表达式不合法,请重新检查!")123   
View Code

匿名函数:1. 没有名字 2:函数体自带return

f=lambda x,y,z=1:x+y+zprint(f)print(f(1,2,3))

  

一、time模块

在Python中,通常有这几种方式来表示时间:

  • 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
  • 格式化的时间字符串(Format String)
  • 结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
1 import time2 #--------------------------我们先以当前时间为准,让大家快速认识三种形式的时间3 print(time.time()) # 时间戳:1487130156.4195274 print(time.strftime("%Y-%m-%d %X")) #格式化的时间字符串:'2017-02-15 11:40:53'5 6 print(time.localtime()) #本地时区的struct_time7 print(time.gmtime())    #UTC时区的struct_time
例子1
1 # localtime([secs]) 2 # 将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。 3 time.localtime() 4 time.localtime(1473525444.037215) 5  6 # gmtime([secs]) 和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。 7  8 # mktime(t) : 将一个struct_time转化为时间戳。 9 print(time.mktime(time.localtime()))#1473525749.010 11 12 # strftime(format[, t]) : 把一个代表时间的元组或者struct_time(如由time.localtime()和13 # time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()。如果元组中任何一个14 # 元素越界,ValueError的错误将会被抛出。15 print(time.strftime("%Y-%m-%d %X", time.localtime()))#2016-09-11 00:49:5616 17 # time.strptime(string[, format])18 # 把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。19 print(time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X'))20 #time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6,21 #  tm_wday=3, tm_yday=125, tm_isdst=-1)22 #在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。
例子2

二、random模块

1 import random 2   3 print(random.random())#(0,1)----float    大于0且小于1之间的小数 4   5 print(random.randint(1,3))  #[1,3]    大于等于1且小于等于3之间的整数 6   7 print(random.randrange(1,3)) #[1,3)    大于等于1且小于3之间的整数 8   9 print(random.choice([1,'23',[4,5]]))#1或者23或者[4,5]10  11 print(random.sample([1,'23',[4,5]],2))#列表元素任意2个组合12  13 print(random.uniform(1,3))#大于1小于3的小数,如1.927109612082716 14  15  16 item=[1,3,5,7,9]17 random.shuffle(item) #打乱item的顺序,相当于"洗牌"18 print(item)
例子
1 import random 2 def make_code(n): 3     res='' 4     for i in range(n): 5         s1=chr(random.randint(65,90)) 6         s2=str(random.randint(0,10)) 7         res+=random.choice([s1,s2]) 8     return res 9 10 print(make_code(9))11 12 生成随机验证码
生成随机验证码

三、os模块

os模块是与操作系统交互的一个接口

1 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 2 os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd 3 os.curdir  返回当前目录: ('.') 4 os.pardir  获取当前目录的父目录字符串名:('..') 5 os.makedirs('dirname1/dirname2')    可生成多层递归目录 6 os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 7 os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname 8 os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname 9 os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印10 os.remove()  删除一个文件11 os.rename("oldname","newname")  重命名文件/目录12 os.stat('path/filename')  获取文件/目录信息13 os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"14 os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"15 os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:16 os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'17 os.system("bash command")  运行shell命令,直接显示18 os.environ  获取系统环境变量19 os.path.abspath(path)  返回path规范化的绝对路径20 os.path.split(path)  将path分割成目录和文件名二元组返回21 os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素22 os.path.basename(path)  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素23 os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False24 os.path.isabs(path)  如果path是绝对路径,返回True25 os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False26 os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False27 os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略28 os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间29 os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间30 os.path.getsize(path) 返回path的大小
os模块用法
1 os路径处理 2 #方式一:推荐使用 3 import os 4 #具体应用 5 import os,sys 6 possible_topdir = os.path.normpath(os.path.join( 7     os.path.abspath(__file__), 8     os.pardir, #上一级 9     os.pardir,10     os.pardir11 ))12 sys.path.insert(0,possible_topdir)13 14 15 #方式二:不推荐使用16 os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
使用方法

四、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       返回操作系统平台名称
sys用法
1 def progress(percent,width=50): #51 2     if percent >= 100: 3         # print('\r[%s] 100%%' %(width*'#')) 4         percent=100 5     show_str=('[%%-%ds]' %width) %(int(width*percent/100)*'#') 6     print('\r%s %d%%' %(show_str,percent),file=sys.stdout,flush=True,end='') 7 # 8 total_size=1025121 9 recv_size=010 11 while recv_size < total_size:12     time.sleep(0.01) #模拟下载的网络延迟13     recv_size+=102414     recv_per=int(100*recv_size/total_size)15     progress(recv_per,width=10)
例子:模拟进度条

五、shutil模块

高级的 文件、文件夹、压缩包 处理模块

shutil.copyfileobj(fsrc, fdst[, length])

将文件内容拷贝到另一个文件中

1 import shutil2  3 shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))

 

shutil.copyfile(src, dst)

拷贝文件

1 shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在

 

shutil.copymode(src, dst)

仅拷贝权限。内容、组、用户均不变

1 shutil.copymode('f1.log', 'f2.log') #目标文件必须存在

 

shutil.copystat(src, dst)

仅拷贝状态的信息,包括:mode bits, atime, mtime, flags

1 shutil.copystat('f1.log', 'f2.log') #目标文件必须存在

 

shutil.copy(src, dst)

拷贝文件和权限

1 import shutil2  3 shutil.copy('f1.log', 'f2.log')

 

shutil.copy2(src, dst)

拷贝文件和状态信息

1 import shutil2  3 shutil.copy2('f1.log', 'f2.log')

 

shutil.ignore_patterns(*patterns)

shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹

1 import shutil2  3 shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除 
 
拷贝软连接

 

shutil.rmtree(path[, ignore_errors[, onerror]])

递归的去删除文件

1 import shutil2  3 shutil.rmtree('folder1')

 

shutil.move(src, dst)

递归的去移动文件,它类似mv命令,其实就是重命名。

1 import shutil2  3 shutil.move('folder1', 'folder3')

 

shutil.make_archive(base_name, format,...)

创建压缩包并返回文件路径,例如:zip、tar

创建压缩包并返回文件路径,例如:zip、tar

  • base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    如 data_bak                       =>保存至当前路径
    如:/tmp/data_bak =>保存至/tmp/
  • format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
  • root_dir: 要压缩的文件夹路径(默认当前目录)
  • owner: 用户,默认当前用户
  • group: 组,默认当前组
  • logger: 用于记录日志,通常是logging.Logger对象
  • 1 #将 /data 下的文件打包放置当前程序目录2 import shutil3 ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')4   5   6 #将 /data下的文件打包放置 /tmp/目录7 import shutil8 ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
    例子

     

shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:

 
zipfile压缩解压缩
 
tarfile压缩解压缩

 

六、 json&pickle模块

1 import json 2   3 dic={
'name':'alvin','age':23,'sex':'male'} 4 print(type(dic))#
5 6 j=json.dumps(dic) 7 print(type(j))#
8 9 10 f=open('序列化对象','w')11 f.write(j) #-------------------等价于json.dump(dic,f)12 f.close()13 #-----------------------------反序列化
14 import json15 f=open('序列化对象')16 data=json.loads(f.read())# 等价于data=json.load(f)
json序化例子
import json#dct="{'1':111}"#json 不认单引号#dct=str({"1":111})#报错,因为生成的数据还是单引号:{'one': 1}dct='{"1":"111"}'print(json.loads(dct))#conclusion:#        无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
注意
1 import pickle 2   3 dic={
'name':'alvin','age':23,'sex':'male'} 4 5 print(type(dic))#
6 7 j=pickle.dumps(dic) 8 print(type(j))#
9 10 11 f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes'12 f.write(j) #-------------------等价于pickle.dump(dic,f)13 14 f.close()15 #-------------------------反序列化16 import pickle17 f=open('序列化对象_pickle','rb')18 19 data=pickle.loads(f.read())# 等价于data=pickle.load(f)20 21 22 print(data['age'])
pickle例子

 

转载于:https://www.cnblogs.com/ikere/p/7338481.html

你可能感兴趣的文章
亲测PHpnow 安装环境
查看>>
JavaScript 使用random()在一个范围内生成随机数
查看>>
你真的会玩SQL吗?Case也疯狂
查看>>
connectionstrings-sql server 2012
查看>>
Ubuntu中搭建Hadoop2.5.2完全分布式系统(二)
查看>>
码农最艰巨的十大任务
查看>>
第一次校赛总结
查看>>
二进制反码求和
查看>>
[Jxoi2012]奇怪的道路 BZOJ3195 状压DP
查看>>
写一个字符串反转函数,实现字符串倒序。
查看>>
10.scrapy框架简介和基础应用
查看>>
[转]RGB颜色查询对照表
查看>>
进制转换的知识
查看>>
9月28日学习内容整理:多进程,并发,子进程的创建(multiprocessing模块)
查看>>
3月8日学习内容整理:restframework的视图组件
查看>>
《结对-贪吃蛇游戏-开发环境搭建过程》
查看>>
OO第四阶段总结
查看>>
c#装箱与拆箱
查看>>
列式数据库~clickhouse日常管理
查看>>
Android richtext
查看>>