在数学公式中将对象映射到对象属性

时间:2019-04-02 14:50:29

标签: python python-2.7

我们说我有一些Foo类的对象Obj1,Obj2,Obj3,它具有属性栏。 另外,我有一个数学公式以字符串形式给出,该公式取自excel,并且可能有所不同:

s = "-(Obj1 + Obj2 - Obj3)"

如何计算-(Obj1.bar + Obj2.bar - Obj3.bar)的值

如果必要,则需要Python 2.7

EDIT1:
到目前为止,我可以通过将对象存储在字典dict中来实现此目的,其中key是类型字符串的Obj名称,value是对象本身 映射过程包括以下步骤:

  1. re.findall将s中的Obj名称提取到列表l1 = ["Obj1", "Obj2", "Obj3"]中。

  2. re.split来获取s中所有的数学符号为l2 =['-(', '+', '-', ')']

  3. 此后,我使用以下映射l3 = map(lambda x:dict[x].bar, l1)

  4. 最后我zip l2l3并使用eval。

假设s是从excel提取的,这样使用eval可以吗?

1 个答案:

答案 0 :(得分:0)

以下实现魔术方法,以允许将该对象作为算术运算符(加号,减号等)的操作数进行评估。请注意,__neg__是否定词,由于它是唯一的一元代码,因此我将其分开编写。

一旦实现了这些功能,就可以使用eval内置函数。这种方法的一个缺点是,最终字符串应包装在“ int(...)”或“ float(...)”或“(....... bar”中)以获取最终值。可以通过编写另一个函数轻松地实现自动化(但可以在下面手动完成)。

Python 2.7或3+中的文档相似,但以下是最新文档:

https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types
https://docs.python.org/3/library/operator.html#module-operator
https://docs.python.org/3/library/functions.html#eval

代码:

import operator

def get_magic_fn(operation):
    # used for populating arithmetic magic methods
    def magic_fn(a, b):
        return Obj(operation(float(a), float(b)))
    return magic_fn

class Obj(object):
    # can modify constructor to take other args
    def __init__(self, bar):
        self.bar = bar

    __sub__ = get_magic_fn(operator.sub)
    __add__ = get_magic_fn(operator.add)
    __mul__ = get_magic_fn(operator.mul)
    __rsub__ = get_magic_fn(operator.sub)
    __radd__ = get_magic_fn(operator.add)
    __rmul__ = get_magic_fn(operator.mul)
    __truediv__ = get_magic_fn(operator.truediv)


    def __neg__(self):
        return Obj(-1 * self.bar)

    def __float__(self):
        return float(self.bar)

    def __int__(self):
        return int(self.bar)

obj1 = Obj(1)
obj2 = Obj(2)
obj3 = Obj(3)

s1 = "-(obj1 - obj2 + obj3)"
s2 = "-4 * (obj1 - obj2 * obj3)"
s3 = "obj3 * obj1 / obj2"

print(int(eval(s1)))
print(int(eval(s2)))
print(float(eval(s3)))

使用python 2.7或3+的输出:

-2
20
1.5