Функции в SymPy
Я новичок в 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
3 ответов:
Я новичок в объектах Python...
Иметь вопросы-это здорово, но объекты и классы, стоящие за SymPy, довольно сложны, и изучение основ объектной модели Pythonперед погружением в такую библиотеку настоятельно рекомендуется.
Существует много проблем с предлагаемым кодом:
Чисто языковые ошибки
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на что-то другое с помощью(x+2).subs(x,y), но вы не можете ожидать, что библиотека волшебным образом узнает, что у вас есть что-то особенное в виду дляSymbol('x'), Когда вы пишете(x+2)(4). Вы также можете написатьblah = Symbol('random_string'); (blah+2)(4).Незначительные ошибки симпатии
varэто вспомогательная функция, используемая для создания объектовSymbol, но она предназначена для интерактивного использования в интерпретаторе. Не используйте его в коде библиотеки, поскольку в качестве побочного эффекта он вводит глобальные переменные в пространство имен. Просто используйте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)снова вызовет ошибки.
С этим есть пара проблем.
- Вы не определяете класс как объект
- Вы назвали функцию eval, которая является зарезервированным словом
Попробуйте это:
class Eval(object): def __init__(self,m): self.M = m def fun(self,x): print self.M(x) x = var('x') ak = Eval(x+2) ak.meth(x) x + 2HTH
Ваш код уже может передать функцию объекту. Функции являются первоклассными гражданами в Python, вы можете передать их как любой другой объект. Проблема может быть с вашей версией
sympy. Сравните:>>> import sympy >>> sympy.__version__ '0.7.1.rc1' >>> from sympy.abc import x >>> (x + 2)(x) Traceback (most recent call last): File "<input>", line 1, in <module> TypeError: 'Add' object is not callableИ:
То есть, тот же код работает на>>> import sympy >>> sympy.__version__ '0.7.2' >>> from sympy.abc import x >>> (x + 2)(x) x + 20.7.2, но он не работает на версии0.7.1rc1.
Comments