tags:

views:

66

answers:

5

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.

A: 

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.

gnibbler
Yeah. I'm thinking that moving the code to a different file is probably the best way to do it. Little tiny conditional file importing a bigger file...
Paul McMillan
A: 

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
Chris B.
sys.exit() doesn't work because I'm trying to import these as part of a larger program. Indenting hundreds of lines because of a single conditional seems bad.
Paul McMillan
I thought that might be why you weren't using `sys.exit`. Besides moving the code into another module (where, to be fair, it probably should be indented within a function there as well) I think you're going to have to indent it. It's the Python way!
Chris B.
I suppose indenting is the Python way. The code in question is actually a bunch of import statements, so it doesn't really belong in a function...
Paul McMillan
Ah, but that's not correct. Import statements belong in functions just as much as other statements do. It was strange for me coming from a Java background, but once I wrapped my head around the idea that you _can_ put import statements within conditional blocks (in functions, in try/catch blocks, etc ...) it suddenly made sense. In fact, sometimes you _have_ to put them in functions--to ensure one's fully loaded before another one imports it.
Chris B.
But that's the thing - this is in an __init__, so the whole point is to conditionally set up the namespace with the correct things imported so that the rest of my program can simply import the module in question and use the appropriate bits. If I put them in a function, it won't get them into the module-level namespace. Conditionally importing seems to be the only good option.
Paul McMillan
Well, that's a different question, and not the one you asked. You can either use the `if/else` statement, or import modules and then just assign them to the global namespace. See http://stackoverflow.com/questions/1429814/how-to-programmatically-set-a-global-module-variable
Chris B.
+1  A: 

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
kwatford
The problem is that the "non-sunny" code is mostly imports, which don't work inside a function, and large blocks of imports don't look right when heavily indented.
Paul McMillan
imports work within a function. You can `global` them if they need to be seen outside. It's generally considered poor form, but it works.
bobince
A: 

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.

bennedich
Bad answers are worse than no answers.
Paul McMillan
Yeah, well you requested something that definitely was against common python practice and I gave you what I considered was a matching answer. Anyway, it is a solution. I'd really like to see if there's any other solution that meet your requirements.
bennedich
A: 

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())
Tomasz Wysocki