2

I have three modules a.py, b.py and c.py. The a.py module is the base one. What I want to achieve is to have different behaviour when a.py is imported by b.py and when a.py is imported by c.py. For example:

a.py

def ab():
  return 5

def ac():
  return 6

if __nameoftheimportmodule__ == 'b':
  x = ab() 
elif __nameoftheimportmodule == 'c':
  x = ac() 
else:
  pass

Therefore, calling b.py like this:

b.py

import a
print(a.x)

will return 5 (and for c.py it would return 6).

And my question is whether such a design is possible (e.g. whether there exists such a function that behaves like the above-mentioned nameoftheimportmodule)?

ragoragino
  • 133
  • 1
  • 5

2 Answers2

0

The closest solution I could find to match that behavior is using the inspect module's stack function:

import inspect

def ab():
    return 5

def ac():
    return 6

if inspect.stack()[1][1]  == 'b.py':
    x = ab() 
elif inspect.stack()[1][1]  == 'c.py':
    x = ac() 
else:
    pass

inspect.stack():

Return a list of frame records for the caller’s stack. The first entry in the returned list represents the caller; the last entry represents the outermost call on the stack.

When inspect.stack() is called from a.py, we get

[(<frame object at 0x102c25dd0>, '/Users/home/43985900/a.py', 3, '<module>', ['print inspect.stack()\n'], 0), (<frame object at 0x102c25c20>, 'c.py', 1, '<module>', ['print(a.x)\n'], -1)]

We're interested in "the last entry represents the outermost call on the stack" so we index the stack as stack[1][1] to get 'c.py', which we compared to the calling module's filenames.

Now when we test run the modules we get the expected output:

$ python c.py
6
$ python b.py
5

Adapted from this question's answer: Get name of calling function's module in Python.

Community
  • 1
  • 1
0

You'd have to screw with the import system pretty hard to do that, especially since ordinarily, the module's code won't even run again when the second module imports it. Python will just reuse the same module object created on the first import, with the same value of x stored.

You could do it by replacing __import__, or maybe by using one of the less sledgehammery hooks the import system provides, but it's not at all worth it, and it's not going to lead to programs that are easy to understand or reason about.

user2357112
  • 260,549
  • 28
  • 431
  • 505