1

I'm newbie in python and I'm trying to handle errors but I don't know the most efficient way to handle errors in python. I tried this way, but it seems a bit complex to understand. I think may can exist some other "better" manner to handle it.

def set_bit(value, pos, nbits):
"""
Set bit at position.

Keyword Arguments
    value (int)
        Bitstring value.
    pos (int)
        Position to set bit.
    nbits (int)
        Number of bits.
"""
if isinstance(value, int):
    if value > -1:
        # Positives only
        if isinstance(pos, int):
            if pos > -1:
                if isinstance(nbits, int):
                    if nbits > -1:
                        return get_bistring(value | 2 ** (pos % nbits), nbits)
                    else:
                        raise ValueError(
                            '"nbits" was set {}, but it must be positive only'
                            .format(nbits)
                        )
                else:
                    raise TypeError(
                        '"nbits" was set {}, but it must be int only'
                        .format(type(nbits))
                    )
            else:
                raise ValueError(
                    '"pos" was set {}, but it must be positive only'
                    .format(pos)
                )
        else:
            raise TypeError(
                '"pos" was set {}, but it must be int only'
                .format(type(pos))
            )
    else:
        raise ValueError(
            '"value" was set {}, but it must be positive only'
            .format(value)
        )
else:
    raise TypeError(
        '"value" was set {}, but it must be int only'
        .format(type(value))
    )

2 Answers2

2

You can try to write it like this

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise
kerberos
  • 1,527
  • 2
  • 10
  • 18
2

Invert your logic to simplify your code:

def set_bit(value, pos, nbits):
    """
    Set bit at position.

    Keyword Arguments
        value (int)
            Bitstring value.
        pos (int)
            Position to set bit.
        nbits (int)
            Number of bits.
    """
    if not isinstance(value, int):
        raise TypeError('"value" was set {}, but it must be int only'.format(type(value)))
    if value < 0:
        raise ValueError('"value" was set {}, but it must be positive only'.format(value))
    if not isinstance(pos, int):
        raise TypeError('"pos" was set {}, but it must be int only'.format(type(pos)))
    # and so on...

    # once you finish all your checks, then do what you planned to do

Since raise will automatically cancel the execution of the rest of the function, any code that comes after a conditional raise can assume that the condition didn't apply, so you don't need else statements.

Amber
  • 507,862
  • 82
  • 626
  • 550
  • But didn't try-catch statements be more plausive when handling erros? Seems that if-else statements is not the "best" option for this. – Átila Gama Silva Oct 10 '17 at 01:36
  • @ÁtilaDiasdaGamaeSilva despite the word 'handle' in the title, the question as written is about raising exceptions, not catching them. – Amber Oct 10 '17 at 01:37