orome
orome

Reputation: 48486

Is there a way to test whether a Python function or method has been invoked directly from a shell?

Adding to the list for rake and PHP: Is there a way to test whether a Python function or method has been invoked directly from a Python shell, as opposed to being invoked from within a .py script file?

For example I want to define an expression, test_expr that behaves as follows when the expression appears in a module "shelltest.py",

#!/usr/bin/python
"""Module shelltest.py"""

def test_expr():
    #...

Case (1): it yields True when invoked directly from a shell

>>> import shelltest
>>> shelltest.test_expr()
True

Case (2): it yields False when imported into another module, "other.py" and used in code there

#!/usr/bin/python
"""Module other.py"""

import shelltest

def other_func():
    # ...
    shelltest.test_expr()

which is in turn invoked from a shell

>>> import other
>>> other.other_func()
False

Upvotes: 2

Views: 462

Answers (4)

Marcin
Marcin

Reputation: 49846

If you are at the shell, then __name__ == '__main__'. (In addition, as Ned Batchelder notes, this will only tell you where the function was defined.)

You probably don't want to test this inside a function - it's used instead to distinguish whether a module is being called as a main programme or not. Your functions should probably work the same way regardless, and if you need different functions, you should import a different module containing the same function names.

Do something like this:

if __name__ == '__main__':
   import formain as bumpf
else:
   import forscripts as bumpf

bumpf.domagic()

As to determining whether you're in a web environment - do that in code that will only be called from the web. Python scripts are typically not invoked by CGI, so this doesn't really arise as a use case.

Upvotes: 4

Kiwisauce
Kiwisauce

Reputation: 1344

>>> import sys
>>> called_via_shell = lambda: sys.stdin.isatty()
>>> called_via_shell()
True

More information and code exsamples are here: http://pleac.sourceforge.net/pleac_python/userinterfaces.html#AEN795

Upvotes: 2

Fredrick Brennan
Fredrick Brennan

Reputation: 7357

My favorite way to check for this is to check for sys.ps1.

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print sys.ps1
'>>> '
$ cat > script.py
#!/usr/bin/env python
import sys
print sys.ps1
$ python script.py 
Traceback (most recent call last):
  File "script.py", line 3, in <module>
    print sys.ps1
AttributeError: 'module' object has no attribute 'ps1'

I think the other answers are wrong, because __name__ is __main__ in scripts and in the interactive shell.

Upvotes: 0

Colselaw
Colselaw

Reputation: 1079

If this module was executed from the shell, __name__ will be set to __main__. Otherwise, it will be set to the name of the calling module. You'll see this idiom in modules all the time:

if __name__ == '__main__':
  # do something with the library

Upvotes: -1

Related Questions