PMM
PMM

Reputation: 376

Can the __name__ attribute be accessed from an imported module

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

Answers (2)

martineau
martineau

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

LhasaDad
LhasaDad

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

Related Questions