jezrael
jezrael

Reputation: 862671

Check name of running script file in module

I have 2 app files with import same module:

#app1.py
import settings as s
another code

#app2.py
import settings as s
another code

I need in module check if running first or second app:

#settings.py
#pseudocode
if running app1.py:
   print ('app1')
elif:
   print ('app2')

I check module inspect but no idea.

Also I am open for all better solutions.

EDIT: I feel a bit foolish (I guess it is easy)

I try:

var = None
def foo(a):
    var = a

print (var)

but still None.

Upvotes: 1

Views: 93

Answers (4)

Stael
Stael

Reputation: 2689

As others have said, perhaps this is not the best way to achieve it. If you do want to though, how about using sys.argv to identify the calling module?

app:

import settings as s

settings:

import sys
import os
print sys.argv[0]
# \\path\\to\\app.py
print os.path.split(sys.argv[0])[-1]
# app.py

of course, this gives you the file that was originally run from the command line, so if this is part of a further nested set of imports this won't work for you.

Upvotes: 1

cs95
cs95

Reputation: 402493

I'm not sure it is possible for an importee to know who imported it. Even if it was, it sounds like code smell to me.

Instead, what you can do is delegate the decision of what actions are to be taken by app1 and app2, instead of having settings make that decision.

For example:

settings.py

def foo(value):
    if value == 'app1': 
        # do something        
    else:
        # do something else

app1.py

from settings import foo    
foo('app1')

And so on.


To assign within the function and have it reflect on a global variable. Example:

A.py

var = None

def foo(a):
    global var
    var = a

def print_var():
    print(var)

test.py

import A

A.print_var()
A.foo(123)
A.print_var()

Output:

None
123

Note that globals aren't recommended in general as a programming practice, so use them as little as possible.

Upvotes: 3

zimmerrol
zimmerrol

Reputation: 4951

I think your current approach is not the best way do solve your issue. You can solve this, too, by modifying settings.py slightly. You have two possible ways to go: either the solution of coldspeed, or using delegates. Either way, you have to store the code of your module inside functions.

Another way to solve this issue would be (depending on the amount of code lines which depend on the app name) to pass a function/delegate to the function as a parameter like this:

#settings.py
def theFunction(otherParemters, callback):
    #do something
    callback()

#app1.py
from settings import theFunction
def clb():
    print("called from settings.py")
    #do something app specific here

theFunction(otherParameter, clb)

This appears to be a cleaner solution compared to the inspect solution, as it allows a better separation of the two modules.

It depends highly on the range of application, whether you should choose the first or the second version; maybe you could provide us with more information about the broader issue you are trying to solve.

Upvotes: 1

Ghilas BELHADJ
Ghilas BELHADJ

Reputation: 14096

This works for me.

import inspect
import os

curframe = inspect.currentframe()
calframe = inspect.getouterframes(curframe, 1)

if os.path.basename(calframe[1][1]) == 'app1.py':
   print ('app1')
else:
   print ('app2')

Upvotes: 0

Related Questions