Mikael Fremling
Mikael Fremling

Reputation: 762

Deactivate code in python without changing indentation or adding comments

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.)

Upvotes: 8

Views: 33865

Answers (8)

Mitch Bogart
Mitch Bogart

Reputation: 11

The real reason I want this is for people using the very useful "Check" feature in the Mu editor/sdk.

I like commenting each line to the right of the code. The problem is even a small comment there gets flagged as "Line too long (103 > 88 characters)"

Even in Arduino SDK I can create a macro level function that totally removes code, for example if one uncomments out the #define DEBUG line in the following code snippet. Is Python capable of something similar to that? Whatever is in between 'DB(' and ')', whether within one line or many, gets totally removed before the compiler (or hopefully also interpreter) even sees it:

//#define DEBUG
#ifdef DEBUG
     #define DB(arg) { arg }
#else
     #define DB(arg) {   }
#endif

Upvotes: 0

Nick Thompson
Nick Thompson

Reputation: 11

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`

Upvotes: 0

Robert Pollak
Robert Pollak

Reputation: 4165

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()
#"""

Upvotes: 2

CoMartel
CoMartel

Reputation: 3591

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'
"""

Upvotes: 8

Wayne Werner
Wayne Werner

Reputation: 51787

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

Upvotes: 1

gbronner
gbronner

Reputation: 1945

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...

Upvotes: 2

Aaron Digulla
Aaron Digulla

Reputation: 328536

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)
        '''
    

Upvotes: 2

tobias_k
tobias_k

Reputation: 82889

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.

Upvotes: 4

Related Questions