Python的行为设计模式之解释器模式的 eval

Posted zy_dream

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python的行为设计模式之解释器模式的 eval相关的知识,希望对你有一定的参考价值。

解释器模式,能够以规范的流程解决:
向用户提供某种输入手段,使其可向应用程序中输入“非字符串值”,并允许用户给应用程序编程
懂了没。就是你可以把输入的一些东西,当作一个程序来运行。比如你输入 sum(1+2+3+4),这时会明白说:哦你这是要求和啊,可以的,给你求:sum=10

这里先来看 eval()。书上给的例子蛮有特点的,先看运行结果吧:

Enter an experssion (Ctrl + Z, enter to quit):65
A=65
ANS=65
Enter an experssion (Ctrl + Z, enter to quit):72
A=65, B=72
ANS=72
Enter an experssion (Ctrl + Z, enter to quit):hypotenuser(A,B)
name 'hypotenuser' is not defined
Enter an experssion (Ctrl + Z, enter to quit):hypot(A.B)
'int' object has no attribute 'B'
Enter an experssion (Ctrl + Z, enter to quit):hypot(A,b)
name 'b' is not defined
Enter an experssion (Ctrl + Z, enter to quit):hypot(A,B)
A=65, B=72, C=97.0
ANS=97.0
Enter an experssion (Ctrl + Z, enter to quit):^D
()


Process finished with exit code 0
--------------------------------------------------------------------

只要你输入的是不存在的数学运算或者内容错误,都会有相应的错误提示。
完成以上的功能,我认为主要的关键点是:1.提取所有的数学函数 2.如何用 eval() 对输入的数据进行合成
至于其他的输出格式啦,只要功能完成了,个人觉得那都不是事。
首先,提取所有的数学函数并保存在字典:

def global_context():
    globalContext = globals().copy()
    for name in dir(math):
        if not name.startswith("_"):
            globalContext[name] = getattr(math, name)
    return globalContext


其次,写一个功能来实现参数和数学功能的合成

def calculate(expression, globalContext, localContext, current):
    try:
        result = eval(expression, globalContext, localContext)
        update(localContext, result, current)
        print (", ".join(["=".format(variable, value) for variable, value in localContext.items()]))
        print ("ANS=".format(result))
    except Exception as err:
        print (err)


然后,为了提高程序的可用性,对输入的参数和结果进行保存更新

def update(localContext, result, current):
    localContext[current.letter] = result
    current.letter = chr(ord(current.letter) + 1)
    if current.letter > "Z":
        current.letter = "A"

最后,在主函数让程序跑起来

def main():
    quit = "Ctrl + Z, enter" if sys.platform.startswith("win") else "Ctrl + D"
    prompt = "Enter an experssion ( to quit):".format(quit)
    current = type("_", (), dict(letter="A"))()
    globalContext = global_context()
    localContext = collections.OrderedDict()
    while True:
        try:
            expression = raw_input(prompt)
            if expression:
                calculate(expression, globalContext, localContext, current)
        except EOFError:
            print ()
            break

这是一个逻辑性较高的代码,从提取数学功能->整合->输出->存参实现,紧密连接。
上次是在工厂方法模式造棋盘那里用到了 eval() 来创建对应类的实例,当时确实也看懂了
不过这次 eval() 的使用还是令我惊叹。如果下次谁说,你来自己写一个什么功能的实现,我偷鸡的用 eval() 是不是也可以呢?



以上是关于Python的行为设计模式之解释器模式的 eval的主要内容,如果未能解决你的问题,请参考以下文章

Python之常用设计模式(创建型模式篇)

Python之常用设计模式(创建型模式篇)

Java经典23种设计模式之行为型模式

行为型设计模式之解释器模式

24行为型模式之解释模式

行为型模式之解释器模式