In Python, I'd like to get the variable to which an object is being assigned to. Something like:
class Parent(object):
def __init__(self):
print(???) # Print the variable to which the created instance of
# Parent has been assigned to.
p = Parent() # This should print 'p'.
I have come up with this:
import inspect
class Parent(object):
def __init__(self):
print((inspect.stack()[-1].code_context[-1].split()[0]))
p = Parent()
which, if I understand correctly, literally looks at the outermost call and there takes the left string part, which happens to be the variable - but to me this looks weird. Is there a better way?
Yes, you can do it, using both inspect
and ast
to parse the source code which you can find using inspect.stack()
.
Note that your solution prints "__main__",
for me, and I'm testing on Python 3.5.2, so the answer might be slightly different for other Python versions.
import inspect
import ast
class Parent(object):
def __init__(self):
frame = inspect.stack()[1]
# Parse python syntax of the assignment line
st = ast.parse(frame.code_context[0].strip())
stmt = st.body[0]
# Assume class being instanced as simple assign statement
assert(isinstance(stmt, ast.Assign))
# Parse the target the class is assigned to
target = stmt.targets[0]
print(target.id) # prints "p"
p = Parent()
This only works for simple assign statements. If you have a more complex assign statement, say p, n = Parent(), 0
, you will need to add more steps to parsing the AST. In principle, all valid statements involving Parent()
can be parsed, but in some cases there is no assignment involved (e.g. Parser()
).
The code listed above can therefore only serve as an example how to approach the problem, not as a complete solution.