Deactivate code in python without changing indentation or adding comments

Question:

I suspect the answer to this question will be a big NO!
But here goes.

Is there a way to deactivate (temporarily) long code snippets without having to comment every line or putting an if FALSE: and indenting every line?

As an example, say I have the code

for A in range(1,LargeNumber):
    DoSuff(A)
    ###DO Mode stuff
    ###....
    Done(A)

However, since I’m still developing the code I don’t want this lengthy loop to run. My options are as far as I’m aware:

Comment away

#for A in range(1,LargeNumber):
    #DoSuff(A)
    ####DO Mode stuff
    ####....
    #Done(A)

or wrap in a false if-statement

if False:
    for A in range(1,LargeNumber):
        DoSuff(A)
        ###DO Mode stuff
        ###....
        Done(A)

both of which require me to manipulate every line I want to deactivate.

Is there some more clever way of doing this without having to change the indentation or adding comments at every line. (Except maybe putting LargeNumber=0 here.)

Asked By: Mikael Fremling

||

Answers:

Some suggestions:

  • if you have a particular long-running function you want to skip during development, you could define and use a decorator to skip that function and add it to its declaration (of course, this will only work if the function does not return anything that would be used later on)

    def skip(f):
        def _f(*args, **kwargs):
            print("skipped function", f.__name__)
        return _f
    
    @skip
    def long_running_function(foo):
        print("executed function")
    
  • in case you want to skip a loop, as in your example, just add a break statement at the top

    for i in range(10):
        break # TODO speed up development; remove for production!
        long_running_function(i)
    

Personally, however, I would just go with mass-commenting the block of code you want to skip.

Answered By: tobias_k

I would use something like feature flags. Feature Flags is a (looks like maybe defunct?) library that provides the sort of functionality that you’re looking for.

You could also create a feature flag context manager that looks something like this:

class SkipWith(Exception): pass

@contextmanager
def feature_flag(flag):

    @contextmanager
    def check_active():
        deactivated = ['four', 'five']
        activated = ['one', 'two', 'three']
        if flag in deactivated:
            if flag == 'five':
                print('Five is right out')
            raise SkipWith()
        else:
            yield
    try:
        yield check_active
    except SkipWith:
        print('Skipping flag')


with feature_flag('one') as check, check():
    print('one')

with feature_flag('two') as check, check():
    print('two')

with feature_flag('five') as check, check():
    print('five')

# Ouput:
# one
# two
# Five is right out
# Skipping flag
Answered By: Wayne Werner

Here are several ways which you can use:

  • Move the code into a function/method. You can now deactivate it by changing a single line.
  • Move the code to a new function in a new module. Create a second module which contains the same function but empty. Switch between the two modules in import
  • Create a config flag and protect the code with an if. That way, you have a single place in your config to enable/disable the code.
  • Move all your code into a class. Split the code that you want to deactivate into a method. Extend the class and overload the method with an empty one. When you use the class, use the base or extended class.
  • If you don’t have multi-line strings in the code, you can use

    for A in range(1,LargeNumber):
        deactivated = '''
        DoSuff(A)
        ###DO Mode stuff
        ###....
        Done(A)
        '''
    
Answered By: Aaron Digulla

As requested, what I proposed :

to comment a large code :

"""
for A in range(1,LargeNumber):
        DoSuff(A)
        DO Mode stuff
        ....
        Done(A)
"""

Everything in between the 2 """ will be commented. However as tobias_k said, it doesn’t work well if you have multi-line strings in your code.

But, as he also said, you can make it work like this :

"""
print 'anything with sinple quotes instead of double quotes'
"""
Answered By: CoMartel
for A in range(1,LargeNumber):
   break
   DoSuff(A)
   ###DO Mode stuff
   ###....
   Done(A)

I’ve generally found that using a ‘pass’, ‘return’, ‘continue’, or ‘break’ works nicely for testing…

Answered By: gbronner

An improvement to @CoMartel’s docstring method is to make it switchable with a single character change:

#"""
for A in range(1,LargeNumber):
    DoSuff(A)
    ###DO Mode stuff
    ###....
    Done(A)
#"""

To disable/reenable the block, simply remove/re-add the leading hash sign (#) in the first line.

This can even be used for a fast switch between two code blocks:

#"""
this_block_is_active_now()
"""
this_block_alternatively_gets_active_when_removing_the_hash_sign()
#"""
Answered By: Robert Pollak

The best way I have found is to create a switch. This keeps all of your otherwise """ comment """ sections from turning each other on and off. It is also easy to disable and run as a code chunk and easy to find and delete for when you want to make the chunk a final version.

lightSwitch = "off"

if lightSwitch = "off":

 pass

else:

 `script`
Answered By: Nick Thompson
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.