如何更改添加运算符到自定义函数op2解决问题的功能?

时间:2016-11-10 04:51:20

标签: python python-2.7 sympy

更新

>>> solve([A(x)*A(y) + A(-1), A(x) + A(-2)], x, y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 12, in __mul__
TypeError: unbound method __multiplyFunction__() must be called with A instance
as first argument (got Symbol instance instead)

class A:
    @staticmethod
    def __additionFunction__(a1, a2):
        return a1*a2 #Put what you want instead of this
    def __multiplyFunction__(a1, a2):
        return a1*a2+a1 #Put what you want instead of this
    def __init__(self, value):
        self.value = value
    def __add__(self, other):
        return self.__class__.__additionFunction__(self.value, other.value)
    def __mul__(self, other):
        return self.__class__.__multiplyFunction__(self.value, other.value)

solve([A(x)*A(y) + A(-1), A(x) + A(-2)], x, y)

UPDATE2:

>>> ss([x*y + -1, x-2], x, y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: solve instance has no __call__ method

 class AA:
    @staticmethod
    def __additionFunction__(a1, a2):
        return a1*a2 #Put what you want instead of this
    def __multiplyFunction__(a1, a2):
        return a1*a2+a1 #Put what you want instead of this
    def __init__(self, value):
        self.value = value
    def __add__(self, other):
        return self.__class__.__additionFunction__(self.value, other.value)
    def __mul__(self, other):
        return self.__class__.__multiplyFunction__(self.value, other.value)


ss = solve(AA)
ss([x*y + -1, x-2], x, y)

想在解决函数中将Add运算符更改为自定义函数op2 然后这解决([x * y - 1,x + 2],x,y) 在求解过程中,参数也会改变添加到自定义函数op2

错误,因为我不知道如何将op2注入作为ast树使用的树

>>> class ChangeAddToMultiply(ast.NodeTransformer, ast2.NodeTransformer): 
...     """Wraps all integers in a call to Integer()""" 
...     def visit_BinOp(self, node): 
...         print(dir(node)) 
...         print(dir(node.left)) 
...         if isinstance(node.op, ast.Add): 
...             ast.Call(Name(id="op2", ctx=ast2.Load()), [node.left, node.right 
], []) 
...         return node 
... 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
NameError: name 'ast2' is not defined 
>>> 
>>> code = inspect.getsourcelines(solve) 
>>> tree = ast.parse(code) 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
  File "C:\Python27\lib\ast.py", line 37, in parse 
    return compile(source, filename, mode, PyCF_ONLY_AST) 
TypeError: expected a readable buffer object 
>>> tree2 = ast.parse("def op2(a,b): return a*b+a") 
>>> tree = ChangeAddToMultiply().visit(tree,tree2) 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
NameError: name 'tree' is not defined 
>>> ast.fix_missing_locations(tree) 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
NameError: name 'tree' is not defined 
>>> co = compile(tree, '<ast>', "exec") 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
NameError: name 'tree' is not defined 
>>> 
>>> exec(code) 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
TypeError: exec: arg 1 must be a string, file, or code object 
>>> exec(co) 

原始代码

import ast 
from __future__ import division 
from sympy import * 
x, y, z, t = symbols('x y z t') 
k, m, n = symbols('k m n', integer=True) 
f, g, h = symbols('f g h', cls=Function) 
import inspect 
def op2(a,b): 
    return a*b+a 

class ChangeAddToMultiply(ast.NodeTransformer, ast2.NodeTransformer): 
    """Wraps all integers in a call to Integer()""" 
    def visit_BinOp(self, node): 
        print(dir(node)) 
        print(dir(node.left)) 
        if isinstance(node.op, ast.Add): 
            ast.Call(Name(id="op2", ctx=ast2.Load()), [node.left, node.right], []) 
        return node 


code = inspect.getsourcelines(solve([x*y - 1, x - 2], x, y)) 
tree = ast.parse(code) 
tree2 = ast.parse("def op2(a,b): return a*b+a") 
tree = ChangeAddToMultiply().visit(tree,tree2) 
ast.fix_missing_locations(tree) 
co = compile(tree, '<ast>', "exec") 

exec(code) 
exec(co) 

1 个答案:

答案 0 :(得分:0)

我猜__add__就是你要找的东西。

class A:
    def __init__(self, value):
        self.value = value

    def __add__(self, other):
        return self.value*other.value + 4

>>> a = A(3)
>>> b = A(4)
>>> a + b
16

修改:

使用已存在的函数替换+运算符的解决方案:

class A:
    @staticmethod
    def additionFunction(a1, a2):
        return a1*a2 #Put what you want instead of this

    def __init__(self, value):
        self.value = value

    def __add__(self, other):
        return self.__class__.additionFunction(self.value, other.value)

这个有点棘手。在我看来,additionFunction意味着属于A类,但Python中没有静态方法。因此,必须从selfself.__class__.additionFunction调用此函数。

为了更进一步,人们可以想象使用元类Addable的解决方案,其构造函数将additionFunction作为参数......但它可能不值得。