576 votes

Meilleures pratiques pour affirmer de Python

Est-il de la performance ou de code de problème de maintenance avec l'aide d' assert dans le cadre de la norme de code au lieu de l'utiliser à des fins de débogage?

Est

assert x >= 0, 'x is less than zero'

mieux ou pire que

if x < 0:
    raise Exception, 'x is less than zero'

Aussi, est-il possible de définir une règle d'entreprise comme if x < 0 raise error qui est toujours vérifiée sans l' try/except/finally donc, si à tout moment dans le code x est inférieur à 0, une erreur est générée, comme si vous définissez assert x < 0 au début d'une fonction, n'importe où dans la fonction où x devient de moins de 0, une exception est levée?

854voto

Deestan Points 7298

Affirme devrait être utilisé pour des conditions de test qui ne devrait jamais se produire. Le but est d'accident dans le cas d'une corruption du programme de l'état.

Les Exceptions doivent être utilisés pour les erreurs qui peuvent éventuellement se produire, et vous devriez presque toujours créer vos propres classes d'Exception.


Par exemple, si vous écrivez une fonction pour lire à partir d'un fichier de configuration dans un dict, la mise en forme incorrecte dans le fichier devrait soulever ConfigurationSyntaxError, tandis que vous pourrez assert que vous n'êtes pas sur le point de revenir None.


Dans votre exemple, si x est une valeur définie par l'intermédiaire d'une interface utilisateur ou à partir d'une source externe, une exception est le meilleur.

Si x est uniquement défini par votre propre code dans le même programme, rendez-vous avec une affirmation.

444voto

John Mee Points 12004

"d'affirmer" les déclarations sont supprimées lorsque la compilation est optimisée. Donc, oui, il y a à la fois les performances et les différences fonctionnelles.

Le code actuel générateur émet pas de code d'une instruction assert lorsque l'optimisation est demandé au moment de la compilation. - Python 2.6.4 Docs

Si vous utilisez assert pour mettre en œuvre les fonctionnalités de l'application, puis d'optimiser le déploiement de la production, vous serez en proie par "mais-on-travaille-dans-dev" les défauts.

Voir PYTHONOPTIMIZE et -O -OO

161voto

Nadia Alramli Points 40381

Pour pouvoir lancer automatiquement une erreur lorsque x devient inférieure à zéro dans l’ensemble de la fonction. Vous pouvez utiliser des descripteurs de la classe. Voici un exemple :

154voto

Lutz Prechelt Points 470

Supposons que vous travaillez sur les 200 000 lignes de code, avec quatre collègues Alice, Bernd, Carl, et Daphné. Ils appellent votre code, vous appelez de leur code.

Ensuite, assert a quatre rôles:

  1. Informer Alice, Bernd, Carl, et Daphne ce que votre code s'attend.
    Supposons que vous disposez d'une méthode qui traite une liste de tuples et la logique du programme peut se briser si les tuples ne sont pas immuables:

    def mymethod(listOfTuples):
        assert(all(type(tp)==tuple for tp in listOfTuples))
    

    C'est plus fiable que l'équivalent de l'information dans la documentation et beaucoup plus facile à entretenir.

  2. Informer l'ordinateur ce que votre code s'attend.
    assert applique le bon comportement de l'appelant de votre code. Si votre code d'appels Alices et Bernd du code appelle la vôtre, puis, sans le assert, si le programme se bloque dans Alices code, Bernd pourrait supposer que c'était Alice de la faute, Alice mène une enquête et pourrait supposer que c'est de votre faute, vous enquêter et de dire Bernd il était en fait son. Beaucoup de travail perdues.
    Avec l'affirme, celui qui reçoit un appel de mal, ils vont rapidement être en mesure de voir que c'était de leur faute, pas la vôtre. Alice, Bernd, et vous avez tous les avantages. Sauve énormément de temps.

  3. Informer les lecteurs de votre code (y compris vous-même) ce que votre code a atteint à un certain point.
    Supposons que vous disposez d'une liste d'entrées, et chacun d'eux peut être propre (qui est bonne) ou il peut être smorsh, trale, gullup, ou twinkled (qui sont pas acceptables). Si c'est smorsh il doit être unsmorshed; si c'est trale il doit être baludoed; si c'est gullup il doit être utilisée (et puis, éventuellement, de rythme, trop); si c'est twinkled il doit être twinkled de nouveau, sauf le jeudi. Vous avez l'idée: C'est compliqué tout ça. Mais le résultat final est (ou devrait être) que toutes les entrées sont propres. La bonne Chose(TM) à faire est de résumer l'effet de votre nettoyage de la boucle tant que

    assert(all(entry.isClean() for entry in mylist))
    

    Cette déclarations enregistre un casse-tête pour tout le monde à essayer de comprendre ce qui exactement est-il que la merveilleuse boucle est atteinte. Et le plus fréquent de ces personnes sera probablement vous-même.

  4. Informer l'ordinateur ce que votre code a atteint à un certain point.
    Si jamais vous oubliez le rythme d'une entrée dans le besoin après le trot, l' assert permettra de sauver votre jour et d'éviter que votre code les pauses chère Daphné est beaucoup plus tard.

Dans mon esprit, assert's deux fins de documentation (1 et 3) et safeguard (2 et 4) sont de valeur égale.
Informer les gens peuvent même être plus précieux que d'informer l'ordinateur car il peut empêcher les très fautes assert vise à attraper (dans le cas 1) et beaucoup de la suite des erreurs dans tous les cas.

19voto

Jason Baker Points 56682

La seule chose qui est vraiment mal avec cette approche est qu’il est difficile de faire une exception très descriptive à l’aide de faire valoir des déclarations. Si vous cherchez la syntaxe plus simple, n’oubliez pas que vous pouvez faire aussi quelque chose comme ceci :

Un autre problème est qu’à l’aide de faire valoir pour vérification de condition normale, c’est que cela rend difficile pour désactiver le débogage affirme utilisant l’option - O.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X