开发者

Terminate importation of module non-fatally?

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 ext开发者_运维知识库remely 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜