我们说我有一些Foo类的对象Obj1,Obj2,Obj3,它具有属性栏。 另外,我有一个数学公式以字符串形式给出,该公式取自excel,并且可能有所不同:
s = "-(Obj1 + Obj2 - Obj3)"
如何计算-(Obj1.bar + Obj2.bar - Obj3.bar)
的值
如果必要,则需要Python 2.7
EDIT1:
到目前为止,我可以通过将对象存储在字典dict
中来实现此目的,其中key是类型字符串的Obj名称,value是对象本身
映射过程包括以下步骤:
re.findall
将s中的Obj名称提取到列表l1 = ["Obj1", "Obj2", "Obj3"]
中。
re.split
来获取s
中所有的数学符号为l2 =['-(', '+', '-', ')']
。
此后,我使用以下映射l3 = map(lambda x:dict[x].bar, l1)
。
最后我zip
l2
和l3
并使用eval。
假设s
是从excel提取的,这样使用eval可以吗?
答案 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