Reputation: 335
Using __name__
inside a method references the module where the class was defined.
Is there a way instead for an object to get the module where it has been instantiated?
Upvotes: 0
Views: 50
Reputation: 110248
So - Python's dynamism allows a function to check the frame object where it was called from. .
It would be better if you could pass the module explicitly to the class constructor, though:
class MyObject:
def __init__(self, module):
self.module = module
...
And in the other files:
m = MyObject(__name__)
But, as I mentioned in the first line, you can get to the code calling
a module - save if you have an specialized metaclass, the code calling one class's __init__
is where the object is instantiated. So you can write:
import inspect
class MyObject:
def __init__(self, module):
caller_frame = inspect.currentframe().f_back
self.module = caller_frame.f_globals.get("__name__", "<unknown module>")
...
The Frame object is an internal Python object that keeps the execution state of a code context while the program is being run. It contain references to globals and locals variables available to that frame, as well as code object, current source line, and so on. The topmost frame (0) is the current frame in execution - the second one to the top (1) is the direct caller of the current function/method. The frame .f_globals
attribute is a direct reference to the globals dictionary - the same that would be returned if one would call globals()
inside that frame.
Upvotes: 1