Question: I find difficult to really encapsulate a lot of logic in a reusable manner when writing sympy code I would like to write a function in the following way: def compute_integral(fn): s = symbols_new() # do not apply lexicographic identity, this symbol identity is unique return integrate( fn(s), (s, 0, 1))  If I just use the usual symbols() to instantiate s, I risk fn having the same symbol inside its defining expression somewhere, for instance the following can occur: def compute_integral(fn): s = symbols("s") return integrate(fn(s), (s, 0, 1)) ... import sympy as sp from sympy.abc import * t = sp.sin(3 + s) f = sp.lambdify([x], x**2 + t * s * x) compute_integral(f) #< ---- symbol s is already present in the function, now the integral will produce the wrong result  What I'm doing right now to minimize this issue is less than ideal: compute_integral_local_var = 0 def compute_integral(fn): global compute_integral_local_var compute_integral_local_var += 1 s = symbols("local_{}".format(compute_integral_local_var)) return integrate(fn(s), (s, 0, 1))  I want to avoid these kind of collisions without having to add a special global variable. Any better approaches to achieve this type of encapsulation within the sympy API?

Answer: I'm using the latest sympy, version 1.13.2, and the code block you provided doesn't run: it raises an error. There seems to be some misconceptions that I'd like to clarify. Consider this code block: import sympy as sp from sympy.abc import s, x t = sp.sin(3 + s) print("t:", t) e = x**2 + t * s * x print("e:", e) # t: sin(s + 3) # e: s*x*sin(s + 3) + x**2  Here, I create two symbolic expressions, t and e. t contains a symbolic function, sin, and e is composed of t. You can consider e as a function, but in sympy terminology, e is a symbolic expression. Next, in your example you executed something like this: f = sp.lambdify([x], e)  which creates a numerical function which will be evaluated by NumPy. Then, you attempted to integrate symbolically this numerical function, which is absolutely wrong. With SymPy, you can only perform symbolic integrations of symbolic expressions. If all you are trying to perform is a symbolic integration, then this command is sufficient: sp.integrate(e, (x, 0, 1)) # s*sin(s + 3)/2 + 1/3  If you'd like to integrate multiple symbolic expressions over the same range, then you can create a custom function: def compute_integral(expr, sym): return sp.integrate(expr, (sym, 0, 1)) print(compute_integral(e, x)) # s*sin(s + 3)/2 + 1/3 print(compute_integral(t, x)) # sin(s + 3)  EDIT: Based on the little details you shared, python's lambda function and sympy's Dummy symbols might get what you want. A Dummy symbol is guaranteed to be unique: it is used when a temporary symbol is needed or when a name of a symbol is not important. def compute_integral(func): s = sp.Dummy() return sp.integrate(func(s), (s, 0, 1)) t = sp.sin(3 + s) f = lambda x: x**2 + t * s * x compute_integral(f) # s*sin(s + 3)/2 + 1/3  Please, please, please: don't use functions created with lambdify as arguments of sympy functions: it generally doesn't work. You provided the following example: from sympy.abc import r, s sp.lambdify([r], r**2)(s).diff(s) # out: 2*s  You were lucky, the numerical function generated by lambdify only contains plain python operations (a multiplication, in this cae). Should the original symbolic expression contain other functions, like sin, cos, exp, etc..., you would get an error: sp.lambdify([r], sin(r))(s).diff(s)  --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) AttributeError: 'Symbol' object has no attribute 'sin' The above exception was the direct cause of the following exception: TypeError Traceback (most recent call last) Cell In[50], line 1 ----> 1 sp.lambdify([r], sin(r))(s).diff(s) File <lambdifygenerated-4>:2, in _lambdifygenerated(r) 1 def _lambdifygenerated(r): ----> 2 return sin(r) TypeError: loop of ufunc does not support argument 0 of type Symbol which has no callable sin method