繁体   English   中英

如何在Sympy的求解函数中将添加运算符添加到自定义函数op2?

[英]how to change Add operator to custom function op2 in solve function of 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)

更新2:

>>> 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)

想要在solve函数中将Add运算符更改为自定义函数op2,然后在求解过程中将此solve([x * y-1,x + 2],x,y)更改,参数也将更改为Add to custom function op2

错误,因为我不知道如何将op2作为ast树使用的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) 

我想__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中没有诸如静态方法之类的东西。 因此,必须从self调用此函数: self.__class__.additionFunction

更进一步,可以想象使用一个元类Addable的解决方案,该类的构造函数将additionFunction作为参数...但是,这可能不值得。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM