Python number-like class that remembers arithmetic operations?

前端 未结 5 605
甜味超标
甜味超标 2020-12-05 05:46

I\'m wondering if there exists a python module that would allow me to do something like this:

x = MagicNumber()
x.value = 3
y = 2 * (x + 2) ** 2 - 8
print y          


        
5条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-05 06:20

    Something like this?

    import operator
    
    MAKE_BINARY  = lambda opfn : lambda self,other : BinaryOp(self, asMagicNumber(other), opfn)
    MAKE_RBINARY = lambda opfn : lambda self,other : BinaryOp(asMagicNumber(other), self, opfn)
    
    class MagicNumber(object):
        __add__  = MAKE_BINARY(operator.add)
        __sub__  = MAKE_BINARY(operator.sub)
        __mul__  = MAKE_BINARY(operator.mul)
        __radd__ = MAKE_RBINARY(operator.add)
        __rsub__ = MAKE_RBINARY(operator.sub)
        __rmul__ = MAKE_RBINARY(operator.mul)
        # __div__  = MAKE_BINARY(operator.div)
        # __rdiv__ = MAKE_RBINARY(operator.div)
        __truediv__ = MAKE_BINARY(operator.truediv)
        __rtruediv__ = MAKE_RBINARY(operator.truediv)
        __floordiv__ = MAKE_BINARY(operator.floordiv)
        __rfloordiv__ = MAKE_RBINARY(operator.floordiv)
    
        def __neg__(self, other):
            return UnaryOp(self, lambda x : -x)
    
        @property
        def value(self):
            return self.eval()
    
    class Constant(MagicNumber):
        def __init__(self, value):
            self.value_ = value
    
        def eval(self):
            return self.value_
    
    class Parameter(Constant):
        def __init__(self):
            super(Parameter, self).__init__(0.0)
    
        def setValue(self, v):
            self.value_ = v
    
        value = property(fset=setValue, fget=lambda self: self.value_)
    
    class BinaryOp(MagicNumber):
        def __init__(self, op1, op2, operation):
            self.op1 = op1
            self.op2 = op2
            self.opn = operation
    
        def eval(self):
            return self.opn(self.op1.eval(), self.op2.eval())
    
    
    class UnaryOp(MagicNumber):
        def __init__(self, op1, operation):
            self.op1 = op1
            self.operation = operation
    
        def eval(self):
            return self.opn(self.op1.eval())
    
    asMagicNumber = lambda x : x if isinstance(x, MagicNumber) else Constant(x)
    

    And here it is in action:

    x = Parameter()
    # integer division
    y = 2*x*x + 3*x - x//2
    
    # or floating division
    # y = 2*x*x + 3*x - x/2
    
    x.value = 10
    print(y.value)
    # prints 225
    
    x.value = 20
    print(y.value)
    # prints 850
    
    # compute a series of x-y values for the function
    print([(x.value, y.value) for x.value in range(5)])
    # prints [(0, 0), (1, 5), (2, 13), (3, 26), (4, 42)]
    

提交回复
热议问题