python-2.7command-line-argumentspython-module

How to prevent an imported module from 'importing' sys.argv[1:]


I am a python newbie. To pose my question in a comprehensible manner, I created two scripts. One script is named: called_script.py The other script is named: calling_script.py

The following two lines are the code in called_script.py

 import sys
 print str(sys.argv[1]) + '\n\n' + str(dir(sys.argv[1]))

The following two lines are the code in calling_script.py

 import sys
 import called_script

If I feed 'foo' as a command line argument to 'calling_script.py', foo will appear as sys.argv[1] in 'called_script.py'

Is there any code that I could add to 'called_script.py' so that 'called_script.py' could ascertain whether sys.argv[1] was passed to it from the command line, or whether sys.argv[1] was passed to it from 'main'?

Also, I am curious to know whether it is possible to prevent e.g., sys.argv[1] from being passed from main to an imported module, and where I could find some reading on this topic.

Thank you for any help. It is much appreciated.

                      Marc

Solution

  • Is there any code that I could add to 'called_script.py' so that 'called_script.py' could ascertain whether sys.argv[1] was passed to it from the command line, or whether sys.argv[1] was passed to it from 'main'?

    Fundamentally, no, because command line arguments aren't passed to modules, they're passed to Python, which puts them in sys.argv. Since all the modules are sharing the same sys, they'll all see the same sys.argv, and that's that.

    That said, you can take advantage of __name__, which is set to __main__ only for the main script:

    ~/coding$ python calling_script.py fred
    called_script says __name__ is: called_script
    calling_script says __name__ is: __main__
    

    So you could use something like

    args = sys.argv if __name__ == '__main__' else [whatever_you_want]
    

    and then use args to get the equivalent of a module-specific sys.argv. Similarly, you could branch on __name__ at the very start of calling_script.py, stash sys.argv, and then modify the one in sys (ick).

    But generally speaking, you shouldn't need to use sys.argv anywhere outside your main program anyway. If you need access to sys.argv in multiple places your interface probably isn't separated enough from your routines.