Sympy получить имя символа - PullRequest
1 голос
/ 22 января 2020

Я могу получить имя «неопределенного» символа:

import sympy as sym
knodef = sym.Symbol('k_{nodef}')
print(type(knodef))
sym.pprint(knodef.name)

<class 'sympy.core.symbol.Symbol'>
k_{nodef}

Но как только я определю его как выражение, я больше не смогу получить имя.

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>

Как я могу получить имя kdef?

Аналогично для функций ...

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}

... (есть ли в этом случае эквивалент определения символ)?

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Как вы продемонстрировали, атрибут name Символа и Функции может использоваться для возврата строковой формы «имени». Для UndefinedFunction вы можете использовать .func.name для получения этой строки, но для определенного FunctionClass вы можете просто использовать str для атрибута func:

>>> 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'
0 голосов
/ 23 января 2020

Ответ основан на комментариях hpaulj и скрытых экспериментов и обучения ...

Назначение kdef = sym.Symbol('k_{def}') присваивает имя 'k_{def}', потому что это атрибут класса sym.Symbol.

Позднее присваивание kdef = sym.tan(b*x) просто определяет новый объект класса sym.tan и использует kdef в качестве переменной для него, но на самом деле оно не имеет ничего общего с предыдущим объектом. Таким образом, на данный момент больше нет связи между kdef и 'k_{def}'.

Это легко увидеть с помощью:

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

Это даже происходит с присвоениями того же типа, где в принципе можно использовать один и тот же точный блок памяти:

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

Кроме того, также оказывается, что класс sym.tan не имеет name, поэтому получить его невозможно, потому что он не существовать. Поскольку данная переменная может иметь или не иметь name, можно просто try / expect или запросить dir().

...