Sympy: reducing custom function as string with sympify?

Viewed 202

Is there a solution to sympify() strings including custom methods?

Sympy has the beautiful function sympify.

  • It can reduce strings to sympy-functions and reduce all expressions. Nice!
  • It allows to add 'sympify'-able functions as class.

This is the official example.

from sympy import Matrix, sympify

class MyList1(object):
    def __iter__(self):
        yield 1
        yield 2
        return
    def __getitem__(self, i): return list(self)[i]
    def _sympy_(self): return Matrix(self)


local_dict= {"MyList1": MyList1}
print(sympify(MyList1()))    # Matrix([[1], [2]])
print(sympify('MyList1()'))  # MyList1()
print(sympify('MyList1()', locals=local_dict))  # <__main__.MyList1 object at 0x0000000006D0AA20>

The last two lines can not be reduced by sympify- our class is obviously not known when sympifying a string. Putting the class into 'locals' did not work for me.

Is there a solution to reduce strings?


2 Answers

I think it did what you wanted...MyList1 doesn't have a method for printing but the data is there:

>>> list(sympify('MyList1()', locals=local_dict))
[1, 2]

I would consider this to be a bug in SymPy. Basically, it isn't calling _sympy_ when it constructs an object from a string. You can work around it by either calling sympify() twice, like sympify(sympify('MyList1()', locals=local_dict)). Under normal operation sympify() should be idempotent so there is no harm in doing this.

Related