Функции в 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
969   3  

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 + 2

HTH

Ваш код уже может передать функцию объекту. Функции являются первоклассными гражданами в 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 + 2
То есть, тот же код работает на 0.7.2, но он не работает на версии 0.7.1rc1.

Comments

    Ничего не найдено.