我是 Python 对象的新手,有很多问题。我需要将一个函数传递给我的对象,然后计算该函数。代码类似这样:
from sympy import var
class eval:
def __init__(self, M):
self.M = M
def fun(self, x):
M = self.M
print M(x)
x = var('x')
ak = eval(x+2)
ak.fun(x)
这是错误:
TypeError
Traceback (most recent call last)
(ipython-input-1-b7ef311bd1f0> in <module)()
12
13 ak = eval(x+2)
---> 14 ak.fun(x)
(ipython-input-1-b7ef311bd1f0) in fun(self, x)
7 def fun(self, x):
8 M = self.M
----> 9 print M(x)
10
11 x = var('x')
TypeError: 'Add' object is not callable
最佳答案
I am new to Python objects...
有问题很好,但 SymPy 背后的对象和类非常复杂,需要学习 Python object model 的基础知识强烈建议在深入研究此类库之前。
建议的代码有很多问题:
纯语言相关的错误
eval
是内置的,所以覆盖它是不好的风格- 使用旧式类
像使用某种语言扩展一样使用 SymPy
SymPy 不提供用于创建 python 函数的新语法。特别是,(x+2)(4)
不会给你6
。如果你想要这个,只需编写 myfun = lambda _: _+2; fun(4)
不使用 SymPy。
x+2
是一个 SymPy 对象 (Add(Symbol('x')+Integer(2))
),而不是一些 python AST。您可以使用 (x+2).subs(x,y)
将 x
替换为其他内容,但您不能指望库神奇地知道您在在编写 (x+2)(4)
时请注意 Symbol('x')
。你也可以这样写 blah = Symbol('random_string'); (blah+2)(4)
.
轻微的 SymPy 错误
var
是一个用于创建 Symbol
对象的辅助函数,但它是为了在解释器中进行交互使用。不要在库代码中使用它,因为作为副作用,它会在命名空间中注入(inject)全局变量。只需使用 Symbol('x')
。
现在关于 x+2
是可调用的
在 0.7.2 中实现了递归调用。这意味着您可以创建一个包含未评估的符号对象的 SymPy Expr
树,并将整个树应用于另一个对象,调用向内传播,直到所有未评估的对象都被评估的对象替换。我想上面的描述不清楚所以这里是一个例子:
您想创建一个微分运算符对象D
,它可以执行以下操作:
>>> op = g(y)*D # where g is Function and y is Symbol
>>> op(f(x))
g(y)*f(x).diff(x)
其工作方式是沿树向下(在本例中为 Mul(g(y), D)
),跳过已求值的符号对象并求值未求值的符号对象。
因为很多 SymPy 的用户在阅读数据模型之前就开始使用它,这造成了很多困惑,所以我们将递归调用方案移到了 rc
方法中。在 0.7.3 中,(x+2)(4)
将再次引发错误。
关于python - SymPy 中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16755691/