小编写这篇文章的主要目的,就是给大家介绍一下关于python开发实例,有一些全功能的具体实例,那么,具体内容小编就给大家讲解下。
正文
在之前的基础上进一步实现了全功能表达式求值。
已支持浮点数
已支持字符串的处理,前加一个"(类似lisp语法)
支持减号/负号,一符两用机制
支持所有算术运算符,包括**,//,%
支持全部7个比较运算符
支持与或非3个逻辑运算符
支持自定义数学函数(代码中预设sin函数作为示范)
支持外部提供的变量机制
支持外部设置函数(代码中预设isvar函数作为示范)
支持列表
字典的支持,体现在外部的变量中
结构清晰,易于扩展
具有实用性及学习性
与其说距离DSL只有一步之遥,不如说,DSL机制已经实现。因为可以任意扩展函数,而函数的内容
完全可以自行定义。
完整的源代码
import math opDict={} def addoptr(ch,outLev,inLev,func,parmNum=2): obj={'name':ch,'out':outLev,'in':inLev,'func':func,'parmNum':parmNum} opDict[ch]=obj def makeList(x): if isinstance(x[-2],list): x[-2].append(x[-1]) return x[-2].copy() else: ret=[] ret.append(x[-2]) ret.append(x[-1]) return ret addoptr('#',1,1,None) addoptr('(',90,2,None) addoptr(')',2,None,None) addoptr('[',90,2,None) addoptr(']',2,2,None) addoptr(',',8,9,makeList) addoptr('&',13,14,lambda x:x[-1]and x[-2]) addoptr('and',13,14,lambda x:x[-1]and x[-2]) addoptr('|',11,12,lambda x:x[-1]or x[-2]) addoptr('or',11,12,lambda x:x[-1]or x[-2]) addoptr('~',16,17,lambda x:not x[-1],1) addoptr('not',16,17,lambda x:not x[-1],1) addoptr('=',22,23,lambda x:x[-1]==x[-2]) addoptr('>',22,23,lambda x:x[-2]>x[-1]) addoptr('<',22,23,lambda x:x[-2]<x[-1]) addoptr('>=',22,23,lambda x:x[-2]>=x[-1]) addoptr('<=',22,23,lambda x:x[-2]<=x[-1]) addoptr('!=',22,23,lambda x:x[-2]!=x[-1]) addoptr('<>',22,23,lambda x:x[-2]!=x[-1]) addoptr('in',22,23,lambda x:x[-2]in x[-1]) addoptr('+',31,32,lambda x:x[-2]+x[-1]) addoptr('-',31,32,lambda x:x[-2]-x[-1]) addoptr('*',41,42,lambda x:x[-2]*x[-1]) addoptr('/',41,42,lambda x:x[-2]/x[-1]) addoptr('//',41,42,lambda x:x[-2]//x[-1]) addoptr('%',41,42,lambda x:x[-2]%x[-1]) addoptr('neg',51,52,lambda x:-x[-1],1) addoptr('**',55,56,lambda x:x[-2]**x[-1]) addoptr('sin',61,62,lambda x:math.sin(x[-1]),1) alphabet=[chr(ord('a')+x)for x in range(26)]+[chr(ord('A')+x)for x in range(26)] #print(opChar) #print(opSep) #print(alphabet) def isfloat(str1): try: number=float(str1) except ValueError: return False return True class exprEngine: def __init__(this,isVar=None,getValue=None): this.opndStack=[] this.optrStack=[] this.isVar=isVar this.getValue=getValue #这个状态,特为负号/减号这一特殊符的双含义号所设置 this.negState=0 #内建函数 if isVar: addoptr('isvar',61,62,lambda x:isVar(x[-1]),1) #处理识别 this.oplen=len(max(opDict,key=lambda x:len(x))) this.opChar=[] for i in range(this.oplen): tmp=[x[0:i+1]for x in opDict if len(x)>=i+1] this.opChar.append(tmp) this.opSep=[x[0]for x in opDict if x[0]not in alphabet]+['','t'] print(this.oplen) print(this.opChar) print(this.opSep) def readWord(this,cond): cond=cond.strip() if cond=='': return'','#' if cond[0]in this.opChar[0]: l1=this.oplen for i in range(this.oplen): if cond[:i+1]not in this.opChar<i>: l1=i break print(l1) if cond[:l1]in this.opChar[l1-1]: return cond[:l1],'optr' part='' for ch in cond: if ch in this.opSep: break part+=ch return part,'opnd' def pushoptr(this,optr): #对负号/减号的特殊处理 if optr=='-'and this.negState==0: #这种情况,实际的含义是负号 optr='neg' op=opDict[optr].copy() if len(this.optrStack)==0: this.optrStack.append(op) return opTop=this.optrStack[-1] if op['out']>opTop['in']: this.optrStack.append(op) elif op['out']<opTop['in']: this.popoptr() #这里递归 this.pushoptr(optr) elif op['out']==opTop['in']: #消括号对,简单弹出 this.optrStack.pop() this.negState=0 def popoptr(this): opTop=this.optrStack[-1] a=opTop['parmNum'] if len(this.opndStack)<a: raise Exception('操作数不足,可能有语法错误!') ret=opTop['func'](this.opndStack[-a:]) this.opndStack=this.opndStack[:-a] this.opndStack.append(ret) this.optrStack.pop() def pushopnd(this,opnd): if opnd[0]=='"': #肯定是字符串 this.opndStack.append(opnd[1:]) elif this.isVar and this.isVar(opnd): this.opndStack.append(this.getValue(opnd)) else: if opnd.isdigit(): this.opndStack.append(int(opnd)) elif isfloat(opnd): this.opndStack.append(float(opnd)) else: this.opndStack.append(opnd) this.negState=1 def popopnd(this): if len(this.opndStack)==1: return this.opndStack[0] else: print(this.opndStack) print(this.optrStack) raise Exception('可能存在语法错误。') def eval(this,cond): this.optrStack=[] this.opndStack=[] this.pushoptr('#') while True: aword,kind=this.readWord(cond) print(aword,cond) cond=cond[len(aword):].strip() if kind=='#': this.pushoptr('#') break elif kind=='optr': this.pushoptr(aword) else: if aword=='': raise Exception('操作数为空,肯定有哪里错了。') this.pushopnd(aword) print(this.optrStack) print(this.opndStack) return this.popopnd() if __name__=='__main__': #print(opDict) a=exprEngine() #a.addInfo('水位','低') #b=a.eval('3+5*2=13 and(3+5)*2=16&7-2 in[3,5,7]&12>=15 or a in[a,b,c]') #b=a.eval('sin(-1)<1 and 3+-5=-2') #print(b) #b=a.eval('7*-3') b=a.eval('3**3=27 and 19%5=4 and 21//6=3') print(b)
具体代码就给大家介绍到这里了,希望可以给各位读者带来一定的帮助。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/127801.html
摘要:下面跟大家详细分享一下写爬虫抓取静态网站的全过程。而我们上面说的元字符都代表一定的规则和占据一定的字符。 遇到的需求 前段时间需要快速做个静态展示页面,要求是响应式和较美观。由于时间较短,自己动手写的话也有点麻烦,所以就打算上网找现成的。 中途找到了几个页面发现不错,然后就开始思考怎么把页面给下载下来。 由于之前还没有了解过爬虫,自然也就没有想到可以用爬虫来抓取网页内容。所以我采取的办...
摘要:正则表达式关闭或可选标志。如果所含正则表达式,以表示,在当前位置成功匹配时成功,否则失败。否则指的是八进制字符码的表达式。 正则表达式是个很牛逼的东西,不管是在javascript,还是在Python web开发(http://www.maiziedu.com/course/python-px...)中,我们都会遇到正则表达式,虽然javascript和Python的正则表达式区别不大...
摘要:作者心叶时间中的变量不需要声明。中有六个标准的数据类型数字字符串列表元组集合字典。字符串格式化我叫今年岁心叶我叫心叶今年岁如上所示,字符串支持格式化,当然,出来上面用到的和以外,还有一些别的,具体看文档是不是感觉有点语言的味道。 作者:心叶时间:2018-04-21 09:28 Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。 Python3...
摘要:作者心叶时间中的变量不需要声明。中有六个标准的数据类型数字字符串列表元组集合字典。字符串格式化我叫今年岁心叶我叫心叶今年岁如上所示,字符串支持格式化,当然,出来上面用到的和以外,还有一些别的,具体看文档是不是感觉有点语言的味道。 作者:心叶时间:2018-04-21 09:28 Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。 Python3...
阅读 889·2023-01-14 11:38
阅读 833·2023-01-14 11:04
阅读 684·2023-01-14 10:48
阅读 1887·2023-01-14 10:34
阅读 891·2023-01-14 10:24
阅读 750·2023-01-14 10:18
阅读 479·2023-01-14 10:09
阅读 519·2023-01-14 10:02