Reputation: 123511
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.
Upvotes: 4
Views: 321
Reputation: 23465
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.
Upvotes: 2
Reputation: 23465
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
Upvotes: 1
Reputation: 18281
Very similar to my original answer but slightly scarier
class PartialImport(Exception):
def __init__(self, locals, msg = ""):
self.module = locals
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
from partialimport import PartialImport
class Boo:
pass
if __name__ != "__main__":
raise PartialImport(locals())
class Foo:
pass
This is a fantastically terrible hack that will increase the likelihood of your peers murdering you, but this does work.
Upvotes: 2
Reputation: 18281
try:
import foo
except:
print "Failed to import foo"
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
Upvotes: 1