Caution: This question is deceptively simple in its wording, but it might require an extra intellectual effort to answer it. Trying to take an approach as in How can I get the name of an object in Python? is not a valid answer (you may want to read it first). That approach via an object is, by definition, ambiguous, since any object could be referenced by several names or even none. The approach recommended requires to reach back to the step of parsing, where objects didn't have any existence yet.
Background: I am exploring how to create constructs in Python that allow us to do away with some redundancies, e.g. when doing unit tests:
y = 5
print("%s: %s" % ('y', y))
It would be better to write:
y = 5
print(info(y)) => "Value of 'y' is 5"
Note: This could be solved the other way round, by passing a string and then converting it to an id, e.g. print(info('y')
using something like globals()['y']
. But here we want to go from the id to the string, because there are cases when it it is simpler to do it this way, e.g. when a test routine is passed a list of variables to inspect.
Question: Given an identifier called x in source code, is it possible to write a symbol
function that will return the string corresponding to x?
Semantically, if I write
x = [1, 2, 3, 4] # whatever object
It is obvious from the source code that x is the string 'x'.
In other words, is it possible (in standard Python) to write a symbol function (just to coin a name), which given x, considers it as symbol at the exact place where the function is called, and returns the string 'x'?
x = [1, 2, 3, 4] # whatever object
y = x
symbol(x) = 'x'
symbol(y) = 'y'
The answer is unambiguous in this way: x and y were used as symbols in the source code when the function was called, so the result of symbol must be the string equivalent to the symbol ('x' and 'y' respectively).
I realize that this might be a good piece of 2nd degree introspection work (to find the place in source code (AST?) where the function was called and then to reason with it). Yet could it be done with Python as it exists today?
So if the proposed symbol function works, one should be able to write (typically for a unit test):
x = 5
y = x
print("The value of %s is %s", symbol(x), x) => 5
print("The value of %s is %s", symbol(y), y) => 5
Then the info
function could be written as:
def info(y):
return("%s: %s" % (symbol(y), y))
Note 1: for the sake of generality, the solution should work in standard Python, but answers for other implementations are also acceptable.
Note 2: If you feel that 'symbol' is not the right name for this function or concept, you are welcome to point this out.
Note 3: The is a precise question: given that symbol Y is used in code, write a symbol function, which gives symbol(Y) = 'Y', regardless of object on which the symbol is pointing (class, object, etc.).