Python设计模式:解释器模式

设计模式十三:解释器模式

什么是解释器模式

主要放向:让非初级用户和领域专家使用一门简单的语言来表达想法
一般是高级用户才会有所兴趣。

典型案例

音乐演奏者是现实中解释器模式的例子,
五线谱图形化地表达了声音的音调和持续时间(音乐语言)
音乐演奏者能根据五线谱的符合精确重现声音(语言解释器)

补充知识

领域特定语言(Domain Specific Language ,DSL):针对一个特定领域的有限表达能力的计算机语言。

巴科斯-诺尔形式定义简单语法:
event ::= command token receiver token arguments
command ::= word+
word ::= a collection of one or more alphanumeric characters
token ::= ->
receiver ::= word+
arguments ::= word+

实例代码

from pyparsing import Word,OneOrMore,Optional,Group,Suppress,alphanums

class Gate:
    
    def __init__(self):
        self.is_open = False

    def __str__(self):
        return 'open' if self.is_open else 'closed'
    
    def open(self):
        print('opening the gate')
        self.is_open = True
    
    def close(self):
        print('closing the gate')
        self.is_open = False

class Garage:
    
    def __init__(self):
        self.is_open = False

    def __str__(self):
        return 'open' if self.is_open else 'closed'
    
    def open(self):
        print('opening the garage')
        self.is_open = True
    
    def close(self):
        print('closing the garage')
        self.is_open = False

    
class Aircondition:
    
    def __init__(self):
        self.is_on = False

    def __str__(self):
        return 'on' if self.is_on else 'off'
    
    def turn_on(self):
        print('turning on  the aircondition')
        self.is_open = True
    
    def turn_off(self):
        print('turning off the aircondition')
        self.is_open = False

class Heating:
    
    def __init__(self):
        self.is_on = False

    def __str__(self):
        return 'on' if self.is_on else 'off'
    
    def turn_on(self):
        print('turning on the heating')
        self.is_open = True
    
    def turn_off(self):
        print('turning off the heating')
        self.is_open = False

    
class Boiler:

    def __init__(self):
        self.temperature = 83 

    def __str__(self):
        return 'boiler temperature : {}'.format(self.temperature)

    def increase_temperature(self,amount):
        print('increasing the boiler`s temperature by {} degrees'.format(amount))
        self.temperature += amount

    def decrease_temperature(self,amount):
        print('decreasing the boiler`s temperature by {} degrees'.format(amount))
        self.temperature -= amount
    
class Fridge:

    def __init__(self):
        self.temperature = 2

    def __str__(self):
        return 'fridge temperature: {}'.format(self.temperature)

    def increase_temperature(self,amount):
        print('increasing the fridge`s temperature by {} degrees'.format(amount))
        self.temperature += amount

    def decrease_temperature(self,amount):
        print('decreasing the fridge`s temperature by {} degrees'.format(amount))
        self.temperature -= amount

def main():
    # 巴科斯-诺尔形式定义简单语法
    word = Word(alphanums)
    command= Group(OneOrMore(word))
    token = Suppress("->")
    device = Group(OneOrMore(word))
    argument = Group(OneOrMore(word))
    event = command + token + device + Optional(token + argument)
    # 实例类
    gate = Gate()
    garage = Garage()
    airco = Aircondition()
    heating = Heating()
    boiler = Boiler()
    fridge = Fridge()
    # 使用语法
    tests = ('open -> gate',
            'close -> garage',
            'turn on -> aircondition',
            'turn off -> heating',
            'increase -> boiler temperature -> 5 degrees',
            'decrease -> fridge temperature -> 2 degrees')
    # 解释语法1
    open_actions = {
        'gate':gate.open,
        'garage':garage.open,
        'aircondition':airco.turn_on,
        'heating':heating.turn_on,
        'boiler temperature':boiler.increase_temperature,
        'fridge temperature':fridge.increase_temperature
    }
    # 解释语法2
    close_actions = {
        'gate':gate.close,
        'garage':garage.close,
        'aircondition':airco.turn_off,
        'heating':heating.turn_off,
        'boiler temperature':boiler.decrease_temperature,
        'fridge temperature':fridge.decrease_temperature
    }

    # 分析语言
    for t in tests:
        if len(event.parseString(t))==2: # 不带参数
            cmd,dev = event.parseString(t) # ['turn', 'on'] ['aircondition']
            cmd_str,dev_str = ' '.join(cmd),' '.join(dev) # 需要以 空格 隔开
            if 'open' in cmd_str or 'turn on' in cmd_str:
                open_actions[dev_str]()
            elif 'close' in cmd_str or 'turn off' in cmd_str:
                close_actions[dev_str]()
        elif len(event.parseString(t))==3: # 带参数
            cmd,dev,arg = event.parseString(t) # ['increase'] ['boiler', 'temperature'] ['5', 'degrees']
            cmd_str,dev_str,arg_str = ' '.join(cmd),' '.join(dev),' '.join(arg) # 需要以 空格 隔开
            num_arg = 0
            try:
                num_arg = int(arg_str.split()[0])
            except ValueError as err:
                print("expected number but got: '{}'".format(arg_str[0]))
            if 'increase' in  cmd_str and num_arg > 0:
                open_actions[dev_str](num_arg)
            elif 'decrease' in cmd_str and num_arg > 0:
                close_actions[dev_str](num_arg)

if __name__ == "__main__":
    main()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值