Sympy get Symbol name

Question:

I can get the name of an "undefined" symbol:

import sympy as sym
knodef = sym.Symbol('k_{nodef}')
print(type(knodef))
sym.pprint(knodef.name)
    
<class 'sympy.core.symbol.Symbol'>
k_{nodef}

But as soon as I define it as an expression, I cannot get the name anymore.

kdef = sym.Symbol('k_{def}')
kdef = sym.tan(b*x)
print(type(kdef))
sym.pprint(kdef.name)      # AttributeError: 'tan' object has no attribute 'name'

tan
<Error raised>

How can I get the name of kdef?

Similarly for functions…

knodef2 = sym.Function('k_{nodef2}')
#display(disp.Math(knodef2.name), type(knodef2))
print(type(knodef2))
sym.pprint(knodef2.name)

<class 'sympy.core.function.UndefinedFunction'>
k_{nodef2}

… (is there in this case an equivalent to defining the Symbol)?

Answers:

As you demonstrate, the name attribute of Symbol and Function can be used to return a string form of the “name”. For UndefinedFunction you can use .func.name to get that string, but for defined FunctionClass you can just use str on the func attribute:

>>> s=Symbol('s');f=Function('f');a=f(s);b=tan(s)
>>> s.name
's'
>>> f.name
'f'
>>> a.func.name
'f'
>>> str(b.func)
'tan'
Answered By: smichr

Answer based on comments by hpaulj and ulterior experimentation and learning…

Assigning kdef = sym.Symbol('k_{def}') assigns the name 'k_{def}', because that is an attribute of class sym.Symbol.

Later assigning kdef = sym.tan(b*x) simply defines a new object of class sym.tan, and uses kdef as a variable for it, but it actually has nothing to do with the previous object. So at this point, there is no more association between kdef and 'k_{def}'.

This is easily seen with:

kdef = sym.Symbol('k_{def}')
print('kdef = ', kdef, ', address = ', hex(id(kdef)), sep='')
kdef = sym.tan(b*x)
print('kdef = ', kdef, ', address = ', hex(id(kdef)), sep='')

kdef = k_{def}, address = 0x20f21b58228
kdef = tan(b*x), address = 0x20f21b584f8

This even happens with assignments to the same type, where in principle the same exact memory block could be used:

q = 2.1
print('q = ', q, ', address = ', hex(id(q)), sep='')
q = 30000.1
print('q = ', q, ', address = ', hex(id(q)), sep='')

q = 2.1, address = 0x1c4dbd5d0d0
q = 30000.1, address = 0x1c4dbd5d2b0

Besides, it also turns out that class sym.tan has no name, so it is not possible to get it because it does not exist.
Since a given variable may or may not have a name, one could simply try/expect, or inquire with dir().

Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.