Reputation: 376
Given a module A, which imports a module B, is there a way for a function in module B (used in module A) to access the __name__
attribute from module A without it being passed explicitly (as, for example, a function argument)?
Upvotes: 3
Views: 463
Reputation: 123473
Yes, you can do it by "reaching back" through function call stack one level to get access the calling function's globals stored in the frame's f_globals
attribute.
Here's what I mean:
# The main script.
import module_A
module_A.func()
# module_A.py
import module_B
def func():
module_B.func()
# module_B.py
import sys
def func():
namespace = sys._getframe(1).f_globals # caller's globals
print(f'module_B.func() was called from {namespace["__name__"]}')
Output from running the main script:
module_B.func() was called from module_A
I'd like to add that this is kind of a hacky thing to be doing, so you might want to think twice before doing it in production code.
Upvotes: 1
Reputation: 2143
If you're being called from module A, you may be able to work back the stack frame and get the name of the filename of the function that called the B module function from. Below is some sample code for walking the stack.
import inspect
def recurse(limit):
local_variable = '.' * limit
if limit <= 0:
for frame, filename, line_num, func, source_code, source_index in inspect.stack():
print '%s[%d]\n -> %s' % (filename, line_num, source_code[source_index].strip())
print inspect.getargvalues(frame)
print
return
recurse(limit - 1)
return
if __name__ == '__main__':
recurse(3)
Upvotes: 0