Paul McMillan
Paul McMillan

Reputation: 20107

Stop evaluation within a module

I've gotten used to writing functions that work like this:

def f():
  if sunny:
    return
  #do non-sunny stuff

I'm trying to figure out the equivalent syntax to use within a module. I want to do something like this:

if sunny:
  import tshirt
  #do something here to skip the rest of the file
import raincoat
import umbrella
#continue defining the module for non-sunny conditions

I know I can write this as an if/else but it seems silly to indent the entire rest of my module.

I could move the rest of the code into a separate module and conditionally import it, but that seems painful.

Upvotes: 10

Views: 3007

Answers (6)

jdknight
jdknight

Reputation: 1839

Just in the same situation and I didn't want to indent a whole slew a code in my module. I used exceptions to stop loading a module, caught and ignored the custom exception. This makes my Python module very procedural (which I assume is not ideal), but it saved some massive code changes.

I had a common/support module, which I defined the following in:

import importlib

def loadModule(module):
    try:
        importlib.import_module(module)
    except AbortModuleLoadException:
        pass;

class AbortModuleLoadException(Exception):
    pass;

With this, if I wanted to "cancel" or "stop" loading a module, I would load the module as follows:

loadModule('my_module');

And inside my module, I can throw the following exception for a certain condition:

if <condition>:
    raise AbortModuleLoadException;

Upvotes: 1

Tomasz Wysocki
Tomasz Wysocki

Reputation: 11568

You can use function to do it:

def foo():
    if True:
        import re
        import os
    else:
        import sys
    return locals()

locals().update(foo())

or:

def foo():
    if not True:
        import sys
        return locals()
    import re
    import os

    return locals()

locals().update(foo())

Upvotes: 0

bennedich
bennedich

Reputation: 12377

I would seriously go with this solution:

if sunny:
    print "it's sunny"
else:
    exec '''
print "one"
print "two"
x = 3
print x
# ETC
'''

Seriously not. But it does work.

Upvotes: 0

kenm
kenm

Reputation: 23905

Separate files and extra indentation are probably reasonable given that this is a weird thing to be doing to begin with.

Depending on what you actually need, you might go ahead and process all of the module body and then delete anything that isn't appropriate at some point later.

def foo(): 
  print "foo"
def bar(): 
  print "bar"

if sunny:
  del foo
else:
  del bar

Upvotes: 2

Chris B.
Chris B.

Reputation: 90201

You're going to have to indent your code, one way or the other. The easiest way is to define the code within functions, and call them. That keeps the if/else blocks tidy.

def do_if_sunny():
    pass

def do_if_rainy():
    pass

if sunny:
    do_if_sunny()
else:
    do_if_rainy()

Alternatively, you could always use sys.exit.

if sunny:
    print "It's sunny"
    sys.exit(0)

# Continue with non-sunny conditions

Upvotes: 0

John La Rooy
John La Rooy

Reputation: 304137

Indenting the conditional part seems fine to me. If it is really long - say more than a screenful or two i'd probably move the conditional parts into separate files. Your code will be much easier to read.

Upvotes: 0

Related Questions