web-dev-qa-db-fra.com

Différence entre Raise Try et Assert

Je connais Python depuis un certain temps et la fonction raise et assert sont (ce que j’ai réalisé, c’est que les deux font planter l’application, contrairement à try - sauf), et que je ne vois pas de situation où vous utiliseriez raise ou assert. sur try

Alors, quelle est la différence entre Raise, Try et Assert?

13
Defneit

Affirmer: 

Utilisé lorsque vous voulez "arrêter" le script en fonction d'une certaine condition et renvoyer quelque chose pour aider à déboguer plus rapidement:

list_ = ["a","b","x"]
assert "x" in list_, "x is not in the list"
print("passed") 
#>> prints passed

list_ = ["a","b","c"]
assert "x" in list_, "x is not in the list"
print("passed")
#>> 
Traceback (most recent call last):
  File "python", line 2, in <module>
AssertionError: x is not in the list

Élever:

Deux raisons qui sont utiles pour cela:

1/À utiliser avec try et except block. Générez une erreur de votre choix, peut être personnalisée comme ci-dessous et n'arrête pas le script si vous pass ou contiune le script; ou peut être des erreurs prédéfinies raise ValueError()

class Custom_error(BaseException):
    pass

try:
    print("hello")
    raise Custom_error
    print("world")
except Custom_error:
    print("found it not stopping now")

print("im outside")

>> hello
>> found it not stopping now
>> im outside

A remarqué que cela ne s'est pas arrêté? Nous pouvons l'arrêter en utilisant simplement exit (1) dans le bloc except.

2/Raise peut également être utilisé pour relancer une erreur en cours afin de la faire remonter dans la pile pour voir si quelque chose d'autre peut la gérer. 

except SomeError, e:
     if not can_handle(e):
          raise
     someone_take_care_of_it(e)

Try/Except block:

fait exactement ce que vous pensez, essaie quelque chose, si une erreur se produit, vous l’attrapez et vous vous en occupez comme vous le souhaitez. Aucun exemple car il y en a un ci-dessus.

22
MooingRawr
assert cond, "text"

est élargi à quelque chose comme

if cond == False:
  raise AssertionError("text")

utilisez assert car il est plus lisible.

16
Michal Krzyz

raise - déclenche une exception.

assert - déclenche une exception si une condition donnée est (ou n'est pas) vraie.

try - exécute du code qui pourrait générer une exception et, le cas échéant, l'attraper.

13
John Gordon

Les blocs try/except vous permettent d'attraper et de gérer les exceptions. Les exceptions peuvent être déclenchées par raise, assert et un grand nombre d'erreurs telles que la tentative d'indexer une liste vide. raise est généralement utilisé lorsque vous avez détecté une condition d'erreur. assert est similaire mais l'exception n'est déclenchée que si une condition est remplie.

raise et assert ont une philosophie différente. Il y a beaucoup d'erreurs "normales" dans le code sur lesquelles vous détectez et augmentez les erreurs. Un site Web n'existe peut-être pas ou une valeur de paramètre est hors limites.

Les assertions sont généralement réservées aux problèmes "Je jure que cela ne peut pas arriver" qui semblent se produire de toute façon. Cela ressemble plus au débogage à l'exécution qu'à la détection d'erreur d'exécution normale. Les assertions peuvent être désactivées si vous utilisez l'indicateur -O ou si vous exécutez des fichiers .pyo au lieu de fichiers .pyc. Elles ne doivent donc pas faire partie de la détection d'erreur normale.

Si le code de qualité de la production soulève une exception, déterminez ce que vous avez mal fait. Si cela soulève une AssertionError, vous avez un plus gros problème.

9
tdelaney

Assert est généralement utilisé par le code de test pour s'assurer que quelque chose a fonctionné:

def test_bool():
    assert True != False

Where as try, raise et excepté la gestion des exceptions fictives, méthode privilégiée en python pour gérer et propager les erreurs.

La plupart des bibliothèques et les fonctions intégrées de python vont déclencher une exception d'un type ou d'un autre en cas de problème. Souvent, dans votre propre code, vous souhaiterez également déclencher une exception lorsque vous détectez un problème. Supposons par exemple que vous écriviez un validateur d'adresse électronique et que vous souhaitiez générer une exception si l'adresse ne contenait pas le signe @. vous pourriez avoir quelque chose comme (c'est du code jouet, ne validez pas réellement les emails comme ceci):

def validate_email(address):
    if not "@" in address:
        raise ValueError("Email Addresses must contain @ sign")

Ensuite, ailleurs dans votre code, vous pouvez appeler la fonction validate_email. Si elle échoue, une exception sera levée.

try:
    validate_email("Mynameisjoe.com")
except ValueError as ex:
    print("We can do some special invalid input handling here, Like ask the user to retry the input")
finally:
    close_my_connection()
    print("Finally always runs whether we succeed or not. Good for clean up like shutting things down.")

La chose importante à savoir est que lorsqu'une exception est déclenchée, elle est transmise à la pile d'appels jusqu'à ce qu'elle trouve un gestionnaire. S'il ne trouve jamais de gestionnaire, il bloquera le programme avec l'exception et la trace de la pile.

Une chose que vous ne voulez pas faire est quelque chose comme:

if __== '__main__':
    try:
        print(1/0)
    except Exception as ex:
        pass

Maintenant, vous n'avez aucun moyen de savoir pourquoi votre demande a explosé.

Une chose que vous verrez souvent et qui est ok est quelque chose comme:

import logging
if __== '__main__':
    try:
        print(1/0)
    except Exception as ex:
        logging.exception(ex)
        raise

La relance dans ce cas, car elle n’a pas de paramètre, cause la même erreur. Souvent, dans le code Web, vous verrez quelque chose de similaire qui ne relance pas l’exception car il enverra l’erreur 500 au client, puis poursuivra avec la demande suivante. Dans ce cas, vous ne voulez pas que le programme se termine.

1
Michael Robellard

Les exceptions sont ce que Python (et quelques autres langages) utilisent pour traiter les erreurs qui surviennent lors de l’exécution du code. raise ExceptionName indique qu'il y a une erreur dans le code et spécifie de quel type de problème il s'agit en générant l'exception associée à ce problème. assert expression évaluer expression et déclenche une exception si elle est fausse. 

try est utilisé pour exécuter du code susceptible de générer une exception à laquelle vous vous attendez. Au lieu d'arrêter le programme, vous pouvez "attraper" l'exception et la traiter dans votre code. 

Exemple: Disons que vous avez un dictionnaire et une liste. Vous souhaitez consulter les éléments de la liste du dictionnaire jusqu'à atteindre celui qui ne figure pas dans le dictionnaire:

try:
    for item in my_list:
        print(my_dictionary[item])
except KeyError as e: #KeyError is the Exception raised when a key is not in a dictionary
    print('There is no {} in the dictionary'.format(e.args[0]))
1
Patrick Haugh

Assertions

  • Ne devrait être utilisé qu'à des fins de débogage
  • Bien que similaires à Raise/Exceptions, ils servent différents objectifs, car ils sont utiles pour pointer des scénarios où une erreur de programme ne peut pas être récupérée.
  • Les assertions soulèvent toujours des exceptions AssertionError, voici comment elles fonctionnent:

syntaxe: assert_stmt ::= "assert" expression1 ["," expression2]

au moment de l'exécution, il se traduit par:

if __debug__:
  if not expression1:
    raise AssertionError(expression2)
  • __debug__ est un indicateur intégré généralement vrai, mais si des optimisations sont déclenchées, les assertions seront un code mort => désactivé avec les indicateurs -O et -OO lors du démarrage de Python (ou de la variable d'environnement PYTHONOPTIMIZE dans CPython) , alors, ne comptez pas sur eux pour la logique de code.
  • Ne pas utiliser les affirmations pour la validation des données à cause du point précédent
  • Un bon cas d’utilisation pour les assertions => make programme "explose" si un état inattendu du programme l’arrête dans toutes les circonstances => ainsi, dans les cas où une exception, si elle est interceptée, ferait complètement disparaître le programme.
  • Si vous avez un programme sans bug, alors les assertions ne devraient/ne devraient jamais être déclenchées, elles servent de contrôles de santé pour le programme.
  • Faites attention lorsque vous utilisez des structures de données (telles que des tuples) comme expression1 dans des assertions dont la valeur est True pour des valeurs non vides => les assertions seront toujours déclenchées, ce qui annulera le programme - par exemple: assert (<some_test>, 'warn string') => !)

Vérifier: Attraper de fausses informations de Python sur CI par Dan Bader

Raise/Exceptions

  • Leur objectif est de gérer des scénarios dans lesquels la logique du programme est dans un état exceptionnel, mais vous savez quelle logique récupérer à partir de cet état.
  • Lorsque vous déclenchez une exception, vous pouvez adapter le type de l'exception à l'erreur (meilleur contrôle de la valeur sémantique) et l'attraper plus tard => afin de pouvoir créer plusieurs types d'exceptions que vous savez comment récupérer, et les gérer.
  • Ils constituent un mécanisme permettant de gérer les scénarios connus/attendus d’erreurs d’exécution.
  • Utile pour la validation des données lors de l'utilisation d'instructions if et de la génération d'exceptions de validation par scénario

Essayer

  • Est-ce juste un élément syntaxique de la gestion des exceptions de codage 

BTW, je recommande fortement le livre, "Tricks Python: Le livre" par Dan Bader (from realpython.com )

0
Rui Carvalho