用Python写了一遍约束器

本文通过面向对象的方法,在Python中实现了温度单位之间的转换。基于SICP第三章的约束器概念,使用类如加法器、乘法器和常量等组件构建了一个简易的系统,并演示了摄氏度与华氏度间的转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看了SICP第三章的约束器的例子,用Scheme实现了一遍,现在用Python以OO的方式再实现了一遍:

9C=5(F-32)

感觉上因为命令式用的比较多,还是OO方式比FP好理解。

class adder(object):
    def __init__(self, a1, a2, s):
        self.a1 = a1.connect(self)
        self.a2 = a2.connect(self)
        self.s = s.connect(self)

    def process_new_value(self):
        if self.a1.has_value() and self.a2.has_value():
            self.s.set_value(self.a1.value() + self.a2.value(), self)
        elif self.a1.has_value() and self.s.has_value():
            self.a2.set_value(self.s.value() - self.a1.value(), self)
        elif self.a2.has_value() and self.s.has_value():
            self.a1.set_value(self.s.value() - self.a2.value(), self)

    def process_forget_value(self):
        self.a1.forget_value(self)
        self.a2.forget_value(self)
        self.s.forget_value(self)
        self.process_new_value()

class multiplier(object):
    def __init__(self, a1, a2, p):
        self.a1 = a1.connect(self)
        self.a2 = a2.connect(self)
        self.p = p.connect(self)

    def process_new_value(self):
        if (self.a1.has_value() and self.a1.value() == 0) or (self.a2.has_value() and self.a2.value() == 0):
           self.p.set_value(0, self)

        if self.a1.has_value() and self.a2.has_value():
            self.p.set_value(self.a1.value() * self.a2.value(), self)
        elif self.a1.has_value() and self.p.has_value():
            self.a2.set_value(self.p.value() / self.a1.value(), self)
        elif self.a2.has_value() and self.p.has_value():
            self.a1.set_value(self.p.value() / self.a2.value(), self)

    def process_forget_value(self):
        self.a1.forget_value(self)
        self.a2.forget_value(self)
        self.p.forget_value(self)
        self.process_new_value()

class constant(object):
    def __init__(self, v, connector):
        connector.connect(self)
        connector.set_value(v, self)

    def process_new_value(self): pass
    def process_forget_value(self): pass

class connector(object):
    def __init__(self):
        self.myValue = None
        self.lastSetter = None
        self.constraints = set()

    def connect(self, constraint):
        self.constraints.add(constraint)
        return self

    def has_value(self):
        return self.myValue != None

    def value(self):
        return self.myValue

    def set_value(self, v, setter):
        if self.myValue is None:
            self.myValue, self.lastSetter = v, setter
            map(lambda x: x.process_new_value(),
                [each for each in self.constraints if each != setter])
        elif self.myValue != v:
            raise Exception, "Input confilicat!"

    def forget_value(self, cleaner):
        if self.lastSetter == cleaner:
            self.lastSetter = self.myValue = None
            map(lambda x: x.process_forget_value(), 
                [each for each in self.constraints if each != cleaner])

class probe(object):
    def __init__(self, name, connector):
        self.name = name
        self.connector = connector
        connector.connect(self)

    def output(self, value):
        if value is not None:
            print "Probe : %s = %d" % (self.name, value)
        else:
            print "Probe : %s = ?" % self.name

    def process_new_value(self):
        self.output(self.connector.value())

    def process_forget_value(self):
        self.output(None)

def celsius_fahreneit_converter(c, f):
    u, v, w, x, y = connector(), connector(), connector(), connector(), connector()
    multiplier(c, w, u)
    multiplier(v, x, u)
    adder(v, y, f)
    constant(9, w)
    constant(5, x)
    constant(32, y)

def main():
    c, f = connector(), connector()
    celsius_fahreneit_converter(c, f)
    probe("Celsius temp", c)
    probe("Fahrenheit temp", f)
    c.set_value(25, 'user')
    c.forget_value('user')
    f.set_value(212, 'user')

if __name__ == '__main__':
    main()


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值