Skip to content Skip to sidebar Skip to footer

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?"