How To Know Where An Object Was Instantiated In Python?
I define a class in a given python module. From a few other python files I will create instances of said class. The instances register themselves at object creation, ie during __in
Solution 1:
Without getting into the merits of why would you want to do this, here is a way to do it:
# assume the file is saved as "temp.py"import inspect
classRegisteredObject(object):
def__new__(cls, *args, **kwargs):
new_instance = super(RegisteredObject, cls).__new__(cls, *args, **kwargs)
stack_trace = inspect.stack()
created_at = '%s:%d' % (
stack_trace[1][1], stack_trace[1][2])
new_instance.created_at = created_at
return new_instance
defget_file_of_object_creation(self):
return self.created_at
classMyObject(RegisteredObject):
passdefcreate_A():
return MyObject()
defcreate_B():
return MyObject()
if __name__ == '__main__':
t1 = create_A()
t2 = create_B()
t3 = create_A()
t4 = create_B()
t5 = MyObject()
print'"t1" was created at "%s"' % t1.get_file_of_object_creation()
print'"t2" was created at "%s"' % t2.get_file_of_object_creation()
print'"t3" was created at "%s"' % t3.get_file_of_object_creation()
print'"t4" was created at "%s"' % t4.get_file_of_object_creation()
print'"t5" was created at "%s"' % t5.get_file_of_object_creation()
Output:
$ python temp.py
"t1" was created at "temp.py:19""t2" was created at "temp.py:22""t3" was created at "temp.py:19""t4" was created at "temp.py:22""t5" was created at "temp.py:29"
Solution 2:
All the caveats about this only being a good idea for debugging aside, you can use the inspect
module.
import inspect
def get_caller():
return inspect.stack()[2] # 1 is get_caller's caller
def trace_call():
_, filename, line, function, _, _ = get_caller()
print("Called by %r at %r:%d" % (function, filename, line))
def main():
trace_call()
main()
produces
Called by'main' at 'trace.py':11
Solution 3:
This answer is slightly different in that it does not use inspect.stack
, considering I observed it to be particularly slow in Python 3.
import inspect
classLocatable:def__new__(cls, *_args, **_kwargs):
# Background: http://eli.thegreenplace.net/2012/04/16/python-object-creation-sequence
obj = super().__new__(cls)
obj.location = obj._initialization_location() # pylint: disable=protected-accessreturn obj
@staticmethoddef_initialization_location():
# Background: https://stackoverflow.com/a/42653524/
frame = inspect.currentframe()
whileframe:if frame.f_code.co_name == '<module>':
return {'module': frame.f_globals['__name__'], 'line': frame.f_lineno}
frame = frame.f_back
@propertydefname(self):
module_name = self.__module__
class_name = self.__class__.__qualname__ # pylint: disable=no-memberreturn module_name + '.' + class_name
The above is a base class that can be inherited from.
The location
attribute should contain the name of the module where the class is instantiated, e.g. mypackage.mymodule
.
Post a Comment for "How To Know Where An Object Was Instantiated In Python?"