design de python: pourquoi assert est-il une déclaration et non une fonction?

En Python,assert est une instruction, et non pas une fonction. Était-ce un choix délibéré? Existe-il des avantages à avoir assert être une déclaration (et le mot réservé) au lieu d'une fonction?

Selon docs,assert expression1, expression2 est étendu à

if __debug__:
    if not expression1: raise AssertionError(expression2)

les docs disent aussi que "le générateur de code actuel n'émet aucun code pour une déclaration assert lorsque l'optimisation est demandée au moment de la compilation." Sans connaissant les détails, il semble qu'un cas spécial était nécessaire pour rendre cela possible. Mais alors, un cas particulier pourrait également être utilisé pour optimiser loin des appels à un assert() fonction.

Si assert une fonction, vous pouvez écrire:

assert(some_long_condition,
       "explanation")

Mais parce que assert est un énoncé, le tuple évalue toujours à True, et vous obtenez

SyntaxWarning: assertion is always true, perhaps remove parentheses?

la bonne façon de l'écrire est

assert some_long_condition, 
       "explanation"

qui est sans doute moins jolie.

47
demandé sur nicael 2012-11-15 05:45:30

4 réponses

y a-t-il des avantages à ce que assert soit une instruction (et un mot réservé) au lieu d'une fonction?

  1. ne peut pas être réaffecté à une fonction utilisateur, ce qui signifie qu'il peut être désactivé au moment de la compilation comme @mgilson l'a fait remarquer.
  2. l'évaluation du second paramètre optionnel est reportée jusqu'à ce que l'assertion échoue. Maladroit de faire cela avec des fonctions et des arguments de fonction(devrait passer un lambda.) Pas de report de la l'évaluation du deuxième paramètre introduirait des frais généraux supplémentaires.
28
répondu vladr 2012-11-15 02:38:37

Une des choses merveilleuses au sujet de assert en python et dans d'autres langues (spécifiquement C) est que vous pouvez les supprimer pour optimiser votre code en ajoutant simplement le (optionnellement sur la ligne de commande avec n'importe quel compilateur que j'ai utilisé) ou des options d'optimisation (-O en python). Si assert est devenue une fonction, cette fonctionnalité serait impossible à ajouter à python car vous ne savez pas jusqu'à l'exécution si vous avez le builtin assert fonction ou une fonction définie par l'utilisateur de la même nom.


notez aussi qu'en python, les appels de fonction sont assez chers. Remplacer inline par le code if __debug__: ... est probablement beaucoup plus efficace que de faire un appel de fonction qui pourrait être important si vous mettez un assert énoncé dans une routine critique de performance.

16
répondu mgilson 2012-12-11 22:21:25

Je ne suis pas un expert en Python, mais je crois que la performance est l'une des plus grandes raisons.

si nous avons assert (expression, explication) comme fonction, si l'expression coûte cher à évaluer, même si nous sommes en mode non-debug, Python doit évaluer les deux expressions pour les passer à la fonction assert.

en élargissant l'assert, la déclaration d'expression et d'explication n'est en fait pas évaluée à moins d'être vraiment nécessaire (quand debug évalue à vrai). Je pense qu'il est essentiel si nous voulons faire valoir sans affecter la performance quand ce n'est pas nécessaire (c.-à-d. pas de performance hit dans le système de production).

6
répondu Adrian Shum 2015-03-03 01:22:59

en plus des autres réponses (et sorte de hors-sujet) un conseil. Pour éviter l'utilisation d'antislashs, vous pouvez utiliser la ligne implicite joignant à l'intérieur de la parenthèse. ; -)

au Lieu de:

assert some_long_condition, \
       "explanation"

Vous pouvez écrire:

assert some_long_condition, (
       "explanation")
5
répondu siebz0r 2013-10-01 06:54:24