I'd like use if __name__ != '__main__':
and then end the execution of a script at that point when it's being imported, rather than doing the usual if __name__ == '__main__':
and indentation of all the rest of the code in the file.
However I have been unable to determine what would cause only this to happen and not have other undesirable side-effects. sys.exit()
stops the whole interpreter and all the other things I've tried either raise some sort of exception or are illegal.
Update:
I've selected @trutheality's answer because it accomplishes what I want and is extremely easy to start using. That said, I thought several of the other answers very interesting and/or clever -- thanks to all who responded -- and plan on investigating some of them further as time permits. I had no idea doing what I want could get so involved.
Another Hack:
# code
if __name__ == "__main__": exec("""
# main code
#""")
So... you've lost the indentation, but also the syntax highlighting and any other features of the editor you were using, unless you comment out the if line every time you edit.
Very similar to my original answer but slightly scarier
partialimport.py
class PartialImport(Exception):
def __init__(self, locals, msg = ""):
self.module = locals
main.py
from partialimport import PartialImport
try:
import foo
except PartialImport, e:
#Note e.module and therefore foo will be a Dict and not a module instance!
foo = e.module
foo.py
from partialimport import PartialImport
class Boo:
pass
if __name__ != "__main__":
raise PartialImport(locals())
class Foo:
pass
Disclaimer
This is a fantastically terrible hack that will increase the likelihood of your peers murdering you, but this does work.
main.py
try:
import foo
except:
print "Failed to import foo"
foo.py
At top of file
if __name__ != "__main__":
raise RunTimeError("foo must be run as main, not as a module.")
class foo(Object):
pass
Since python processes a file sequentially, then class Foo would not be defined.
Another thought would be to overload the import logic itself via PEP 302
Best solution IMO: have two files.
module_main.py
import actual_module.py
if __name__ != '__main__':
raise RunTimeError("You should be importing actual_module.py, not module_main.py")
# Your "main" code
actual_module.py
# Actual module code (classes, functions, etc)
This is "clean" in the sense that an exception is thrown only when something is actually wrong -- no one should ever import module_main.py
, they should import actual_module.py
.
April Fools solution
If you're using python 2.3 there is a goto
module from entrian, that apparently works! It was made as an April fools joke, and should never be used, (if you look at the source you'll see why: it adds a lot of overhead) but as a proof of concept it seems like the only way I can find to accomplish what you want in any sort of concise way.
from goto import goto, label
# Code that should always be imported (classes etc.)
if __name__ != "__main__":
goto .end
# Stuff to be executed when this is main, NOT indented
label .end