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.
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?
- 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.
- 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.
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 -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.
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).
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")