Problems in Try (Python)

Asked

Viewed 1,053 times

-1

When I use Try and put 3 operations, if the first one goes wrong it already goes pro except. Is there any way to "improve" this by making it jump to the next action? Can’t make a code where there’s Ry in every instruction.

  • for you not to receive negative points, improve your question to the maximum, give examples, try, demonstrate the error, make a good formatting in your questions is essential to have positive votes and also for users to help you!

3 answers

3

It is not possible try continue on the next line, after an error, for the simple reason that the language has no way of guessing what to do after an error. The programmer describes the behavior after an error in the clause except.

If you had given an example of what you want, it would be easier to illustrate - but it must be very difficult to give an example of this, since it doesn’t even make sense in the real world: in Python, as well as in other imperative languages, the program runs sequentially - a line depends on the lines that ran before it in the same block (function, loop, etc...) if something went wrong in the previous lines, the language has no way of guessing what to do next (even if what you want is to always ignore the error).

You haven’t given any hint as to what kind of program you’re trying to do - so it’s also not possible to give too many suggestions of what you can do for: or not needing a clause try...except every line, or every two three lines, or how to refactor your code so that a pattern that repeats critical instructions after an error is rewritten with blocks try/except which are reusable.

This second thing - refactoring for a Try/except to be used in various situations, can be used within a while for example - or, within a function that receives "what to ask" and "what to do with the answer" - then, instead of, for each question you have a block:

try:
    print("Pergunta...")
    resposta_bruta = input("...")
    resposta_tratada = float(resposta_bruta)
except TypeError:
    print("Por favor, entre uma resposta numérica...")
try:
    print("Pergunta 2...")
    resposta2_bruta = input("...")
    resposta2_tratada = resposta_bruta.split()[1]
except IndexError:
    print("Por favor, entre uma resposta com pelo menos um espaço...")

note that (1) the language has no way to guess what you want to do if you make a mistake - if you want to repeat, or pass to the next question, and (2) this linear form does not even allow the repetition of the question in case of error (unless you repeat the input within itself except, but then if the answer remains incorrect, you have to put another try/except except dento, ad infinitum.

If you instead make a function that receives as parameters what changes from one question to another, the function itself can not only capture the error, but also repeat the question if something goes wrong:

def pergunta(texto, transformacao, erro_esperado, mensagem):
    while True:
        print(texto)
        resp_bruta = input()
        try:
             resp = transformacao(resp_bruta)
        except erro_esperado:
             print(mensagem)
        else:
             # Cláusula "else" do "try/except",  só é executada se
             # não ocorreu nenhum erro
             break  # Este comando encerra o "while True"

        return resp

pergunta("Entre com a medida", float, TypeError, "por favor, digite um número para a medida")
pergunta("Bla bla bla", lambda x: x.split()[1], IndexError, "por favor, inclua pelo menos um espaço")
...

Ready, now your program calls this function for each question - there is only one "Try/except" in the whole program, even if it has 100 questions, and even more, is coded what should be done in case of error (re-submit the question).

In the question you suggest "three operations": you can use the same idea, and execute the operations themselves within a function that receives the operation as a parameter - just take advantage of the language’s ability to pass a function as a parameter - and , if it is a single expression, It can be like a lambda function, as I did in the example above. (The same pattern works, you just don’t need to include "while True" for retentative. But note that in the event of failure, the function will have to return some value that will stay in its variable anyway - it is not possible to simply "ignore the error".

So, if your structure where you don’t want to leave three "Try/except" blocks is like this:

try:
   op1 = <expressão que realiza cálculos e pode dar erro>
   op2 = <expressão que realiza cálculos e pode dar erro>
   op3 = <expressão que realiza cálculos e pode dar erro>
except ...:
   ...

can do:

def reactor(operacao, default=None):
    try:
        return operacao()
    except Exception:
        return default

op1 = reactor(lambda: <expressão que realiza cálculos e pode dar erro>)
op2 = reactor(lambda: <expressão que realiza cálculos e pode dar erro>)
op3 = reactor(lambda: <expressão que realiza cálculos e pode dar erro>)

Note that the language has such powerful introspection features that it would even be possible to create a decorator that automatically modifies a function to automatically have one try/except round each line - and ignore any error and continue on the next line. Only that wouldn’t make sense - because at the end of the day, at the end of a function, if an error occurred, the function’s response is not correct.

1

@Retronietzsche I believe it must be your syntax that is wrong, I tried to reproduce your problem and it did not happen to me:

try:
    pergunta = input('Quantos anos tem? ')
    if pergunta == 'aaa':
        print('Resposta inválida: aaa')
    if pergunta == 'bbb':
        print('Resposta inválida: bbb')
    if pergunta == 'ccc':
        print('Resposta inválida: ccc')
except KeyboardInterrupt:
    print('Processo interrompido!')

It’s a very simple example, but I believe you should set an example.


The idea of try, except is to test critical points of the code, ie places where there is great possibility of errors.

Following what you said, I believe that there is no way, because every mistake will have to have an except

try:
    print(oi)
except:
    print('1º erro')

try:
    print('oi')
except:
    print('2º erro')

try:
    print(OI)
except:
    print('3º erro')

try:
    print('OI')
except:
    print('4º erro')

Structure of error handling:

try:
    código a tentar
except AlgumaExcecao:
    código a executar no caso da exceção
else:
    código a executar caso não ocorra exceção em try
finally:
    código que é executado sempre, independente de haver uma exceção em andamento ou não

In this link you find a little more information and examples.

  • Magno, cara, iae ! I don’t think I was very clear.

  • Try: print(oi) print('oi') print(OI) print('OI') except Exception as e: print(e) It will go straight to the second line, accusing error of undefined variable. It will not print "hi" and "hi", for example. I want to know if there is how to "optimize" Try for during a block of instructions, if one is incorrect, it try to make the next.

  • @Retronietzsche I understood what I meant now, I edited my answer, take a look at it calmly, may have some other user who knows more information to give you.

  • But for that edit your pergunta as this will help people better understand their question, give examples, use the power of Markdown to edit your post!

1

I believe the structure you’re quoting might be something like:

def acao(n):
    if n == 2:
        raise ValueError('n == 2')

try:
    acao(1)
    acao(2)
    acao(3)
except ValueError:
    pass

Where the function acao parameter n=2, fires an exception.

The exceptional treatment, in computer science, is the mechanism responsible for treating the occurrence of conditions that change the normal flow of running computer programs. 1

That is, thinking of flow control, the exception treatment, diverts the normal flow of execution.

As if the above code could be represented:

acao = lambda n: n != 2
if acao(1):
  if acao(2):
     acao(3)

I think you want one continuous flow, where acao(3) is executed independently of the outcome of acao(2): acao(1); acao(2); acao(3);

Speaking specifically of the first example, I believe that a good solution is a wrapper for the function as:

def safe_acao(n):
    try:
        acao(n)
    except ValueError:
        return False
    else:
        return True

sucedidos = list(map(safe_acao, [1, 2, 3]))

Thinking of a General enclosure, where all exceptions could be directed, the same is not possible in Python, but many ways making use of decorators can be found, one of them even more like a banter. 5 6 7

So remember, the exceptions are fundamental, as well as their correct treatment. Any and all systems are subject to them, since their resources are limited (e.g. memory, disk, ...). 8

It is worth mentioning the approach EAFP (It is easier to ask for forgiveness than permission), in contrast to LBYL (Look before you jump), but I won’t go into details. 9

In various ways, give preference to one that makes use of logging, as an example: https://gist.github.com/diosmosis/1148066

Still, I was struck by the use of Suppress of the contextlib, in accordance with reply.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.