28 votes

Existe-t-il un besoin d'un compilateur Python "strict"?

Il existe les outils d'analyse statique pour Python, mais le temps de compilation des contrôles ont tendance à être diamétralement opposée à l' exécution de liaison de la philosophie que Python embrasse. Il est possible d'envelopper le standard de l'interpréteur Python avec un outil d'analyse statique de mettre en place des "use strict"-comme des contraintes, mais nous ne voyons pas l'adoption généralisée d'une telle chose.

Est-il quelque chose à propos de Python qui fait "use strict" comportement inutiles ou surtout indésirables?

Sinon, est le "use strict" comportement inutile, en Perl, en dépit de son adoption généralisée?

Remarque: Par "nécessaires" je veux dire "pratiquement nécessaire", et non pas strictement nécessaire. Évidemment, vous pouvez écrire du Perl sans "use strict", mais (de ce que j'ai vu), la plupart des programmeurs Perl ne l'utiliser.

Remarque: L'interpréteur Python-wrapper n'a pas besoin d' exiger "use strict"des contraintes de -- vous pouvez utiliser un pseudo-pragma similaires à "use strict" qui sera ignoré par l'interpréteur. Je ne parle pas de l'ajout d'une langue de niveau automatique.


Mise à jour: Expliquer ce qu'est ce "use strict" n'en Perl par les commentaires. (Lien vers les docs officielles est dans le premier paragraphe.)

Le "use strict" directive dispose de trois éléments distincts, dont deux seulement sont vraiment intéressants:

  • l'utilisation stricte de vars: Statique des contrôles lexicalement d'étendue variable d'utilisation dans votre programme. (Gardez à l'esprit que, en Python, il n'y a essentiellement qu' global de la portée et de l' local de la portée). De nombreux Python linters de vérifier ce genre de chose. Puisque c'est la seule analyse statique qu'ils peuvent faire, les linters supposent que vous utilisez simple portée lexicale et de vous avertir à propos de choses qui s'affichent mal dans ce sens jusqu'à ce que vous dites-leur de se taire; c'est à dire

    FOO = 12
    foo += 3
    

    Si vous ne faites pas quelque chose de compliqué avec votre espaces de noms, cela peut être utile pour vérifier les fautes de frappe.

  • use strict refs: Empêche la symbolique de l'espace de noms du déréférencement. Python est plus proche de l'analogique est à l'aide de locals() et globals() à symboliques de la liaison et de l'identificateur de recherche.

  • l'utilisation stricte subs: Aucun réel analogique en Python.

32voto

daotoad Points 17916

Eh bien, je ne suis pas beaucoup d'un programmeur python, mais je dirais que la réponse est "OUI".

Tout langage dynamique qui vous permet de créer une variable avec un nom à tout moment, pourrait utiliser une "stricte" pragma.

Stricte vars (une des options pour le strict en Perl, 'use strict' tourne tous à la fois) en Perl exige que toutes les variables sont déclarées avant leur utilisation. Ce qui signifie que ce code:

my $strict_is_good = 'foo';
$strict_iS_good .= 'COMPILE TIME FATAL ERROR';

Génère une erreur fatale au moment de la compilation.

Je ne sais pas de manière à obtenir Python pour rejeter ce code au moment de la compilation:

strict_is_good = 'foo';
strict_iS_good += 'RUN TIME FATAL ERROR';

Vous obtiendrez une exception d'exécution qu' strict_iS_good n'est pas défini. Mais uniquement lorsque le code est exécuté. Si votre suite de tests n'a pas 100% de couverture, vous pouvez facilement l'envoi de ce bug.

Tout le temps, je travaille dans une langue qui n'ont pas ce problème (PHP par exemple), je suis nerveuse. Je ne suis pas un parfait dactylo. Un simple, mais difficile à repérer, faute de frappe peut causer votre code à l'échec d'une manière qui peut être difficile à traquer.

Donc, pour résumer, OUI Python pourrait utiliser une "stricte" pragma pour activer la compilation des contrôles pour des choses qui peuvent être vérifiés au moment de la compilation. Je ne peux pas penser à d'autres vérifications à ajouter, mais un meilleur programmeur Python pourrait probablement penser à certains.

Remarque , je me concentre sur la pragmatique de l'effet de stict vars en Perl, et je suis abstraction de certains détails. Si vous voulez vraiment connaître tous les détails, voir le perldoc strict.

Mise à jour: des Réponses à certains commentaires

Jason Baker : Statique pions comme pylint sont utiles. Mais elles représentent une étape supplémentaire, ce qui peut être et est souvent ignorée. Le renforcement de certaines vérifications de base dans le compilateur garantit que ces contrôles sont effectués régulièrement. Si ces contrôles sont contrôlables par un pragma, même l'objection concernant le coût des contrôles devient inutile.

popcnt : je sais que python génère une exception. Je l'ai dit plus. Je préconise moment de la compilation, la vérification de la mesure du possible. Merci de relire le post.

mpeters : Pas d'ordinateur, l'analyse de code pouvez trouver toutes les erreurs--ce qui revient à résoudre le problème de l'arrêt. Pire, pour trouver les fautes de frappe dans les affectations, votre compilateur aurait besoin de connaître vos intentions et de trouver des endroits où vos intentions diffèrent à partir de votre code. C'est assez clairement impossible.

Toutefois, cela ne signifie pas qu'aucune vérification ne doit être fait. Si il y a des classes de problèmes qui sont faciles à détecter, alors il est logique de les piéger.

Je ne suis pas assez familier avec pylint et pychecker-à-dire que les classes d'erreurs, ils l'attraper. Comme je l'ai dit je suis très inexpérimenté avec python.

Ces analyse statique de programmes sont utiles. Cependant, je crois que, si on double les capacités de la compilation, le compilateur va toujours être dans une position de "savoir" en savoir plus sur le programme de toute vérification statique pourrait. Il semble un gaspillage de ne pas prendre avantage de cette de réduire les erreurs, si possible.

Mise à jour 2:

cdleary - En théorie, je suis d'accord avec vous, un analyseur statique ne peut faire de la validation, le compilateur peut. Et dans le cas de Python, il devrait être suffisant.

Toutefois, si votre compilateur est assez complexe (surtout si vous avez beaucoup de pragmas changer la manière dont la compilation se produit, ou si comme Perl, vous pouvez exécuter du code lors de la compilation), alors l'analyseur statique doit s'approcher de la complexité du compilateur/interpréteur de faire l'analyse.

Heh, tous ce que parler de complexe de compilateurs et d'exécuter du code lors de la compilation montre mon Perl arrière-plan.

Ma compréhension est que Python n'a pas pragmas et ne peut pas exécuter du code arbitraire au moment de la compilation. Donc, à moins que je me trompe ou ces fonctionnalités sont ajoutées, relativement simple analyseur dans l'analyseur statique devrait suffire. Il serait certainement utile de force de ces contrôles à chaque exécution. Bien sûr, je ferais c'est avec un pragma.

Une fois que vous ajoutez des pragmas pour le mélange, vous avez commencé à descendre une pente glissante, et la complexité de vous l'analyseur doit croître en proportion de la puissance et de la souplesse que vous fournissez dans votre pragmas. Si vous n'êtes pas prudent, vous pouvez retrouver comme Perl, puis "seulement python peut analyser Python," a l'avenir, je ne veux pas voir.

Peut-être un commutateur de ligne de commande serait une meilleure façon d'ajouter forcé l'analyse statique ;)

(En aucune façon l'intention d'attaquer de Python capacités quand je dis qu'il ne peut pas futz avec compilation comportement comme Perl. J'ai l'intuition que c'est une conception soigneusement réfléchie décision, et je vois de la sagesse en elle. Perl extrême flexibilité au moment de la compilation est, à mon humble avis, une grande force et d'une terrible faiblesse de la langue; je vois de la sagesse dans cette approche.)

11voto

S.Lott Points 207588

"le moment de l'exécution de liaison de la philosophie que Python embrasse... en fait "use strict" comportement inutiles [et] surtout indésirables"

Assez bon résumé. Merci.

C'est essentiellement cela. Les outils d'analyse statique de ne pas aider Python assez pour être utile.


Modifier

"Je pose la question pour nous de l'introspection sur pourquoi nous n'avons pas besoin de cela, et, par ailleurs, pourquoi les programmeurs Perl pense qu'ils n'en ont besoin."

La raison en est précisément la raison pour laquelle vous a déjà donné. Nous n'avons pas besoin d'elle car elle n'aide pas. Clairement, vous n'aimez pas la réponse, mais il n'y a pas beaucoup plus à dire. Au moment de la compilation ou de pré-moment de la compilation, la vérification ne peut tout simplement pas aider.

Cependant, puisque vous avez pris le temps de posé de nouveau la question, je vais vous apporter plus d'éléments pour la réponse vous a déjà donné.

J'écris Java presque autant que j'écris en Python. Java est statique type de vérification n'empêche pas des problèmes de logique; il n'est pas de faciliter la rencontre des exigences de performance; il n'a pas d'aider à répondre aux cas d'utilisation. Il n'a même pas de réduire le volume de tests unitaires.

Alors que la vérification des types statiques ne tache occasionnelle d'une mauvaise utilisation d'une méthode, vous trouvez cela tout aussi rapidement en Python. En Python vous trouverez à l'unité de temps de test, car il ne s'exécute pas. Note: je ne dis pas de mal types se retrouvent avec plein de bons tests unitaires, je dis que la plupart des mauvais type de problèmes sont détectés par les exceptions non gérées où la chose n'est tout simplement pas courir assez loin pour se rendre à tester des assertions.

La raison en est Pythoneux ne perdez pas de temps sur la vérification statique est simple. Nous n'avons pas besoin il. Il n'offre pas toute la valeur. C'est un niveau d'analyse qui n'a pas d'avantage économique. Cela ne me rend pas plus en mesure de résoudre les vrais problèmes des vrais gens ont avec leurs données réelles.

Regardez les plus populaires, Python questions de langue (pas du domaine du problème ou de la bibliothèque) connexes.

http://stackoverflow.com/questions/26595/is-there-any-difference-between-foo-is-none-and-foo-none -- == vs is. Pas de vérification statique peut vous aider avec ceci. Aussi, voir http://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python

http://stackoverflow.com/questions/36901/what-does-and-do-for-python-parameters -- *x donne une liste, **x donne un dictionnaire. Si vous ne le connaissez pas, votre programme meurt immédiatement lorsque vous essayez de faire quelque chose d'inapproprié pour ces types. "Que faire si votre programme ne fait jamais rien "inappropriées"". Alors votre programme fonctionne. 'nuff said.

http://stackoverflow.com/questions/36932/whats-the-best-way-to-implement-an-enum-in-python -- c'est un plaidoyer pour une sorte de limité-type de domaine. Une classe avec classe les valeurs de niveau assez bien fait le travail. "Si quelqu'un modifie l'affectation". Facile à construire. Remplacer __set__ de soulever une exception. Oui la vérification statique apercevrez peut-être cela. Non, ce n'est pas le cas dans la pratique que quelqu'un devient confus au sujet d'un enum constante et une variable; et quand ils le font, il est facile à repérer au moment de l'exécution. "Si la logique n'est jamais exécuté". Eh bien, c'est une mauvaise conception et les pauvres de tests unitaires. Jeter une erreur du compilateur et de mettre à mal la logique qui n'est jamais testé n'est pas mieux que ce qui se passe dans un langage dynamique lorsqu'il n'est jamais testé.

http://stackoverflow.com/questions/47789/generator-expressions-vs-list-compre

10voto

bobince Points 270740

Python n'avoir quelque chose qui puisse changer la syntaxe du script:

from __future__ import print_function

et divers autres futurs-des entités qui ont une syntaxe implications. C'est juste que Python syntaxe a été plus stricte, plus stable et moins bien défini que historique Perl; le genre de choses que "strict refs" et "strict subs' interdire n'ont jamais existé en Python.

"stricte var est principalement destiné à arrêter typoed références et a manqué" mon de la création accidentelle globals (ainsi, les variables de package Perl termes). Cela ne peut pas arriver en Python comme nues affectations par défaut de local de déclaration, et nu non affecté symboles, une exception.

(Il est encore le cas où les utilisateurs accidentellement essayer à l'écriture grâce à un mondial, sans le déclarer avec un "mondiale" de l'énoncé, provoquant soit accidentelle local ou, plus souvent, un UnboundLocalError. Ceci tend à être appris assez rapidement, mais il est une cause défendable, où le fait d'avoir à déclarer vos locaux pourrait aider. Bien que peu connu de Python pour les programmeurs accepter la lisibilité fardeau.)

Autre langue et de la bibliothèque des changements qui n'impliquent pas la syntaxe sont traitées à travers les mises en garde du système.

7voto

mpeters Points 3304

Je pense qu'il y a une certaine confusion dans la ce qui "use strict" n'a, d'après les commentaires, je vais voir. Il ne tourne pas sur le moment de la compilation, les vérifications de type (être comme Java). En ce sens, Perl progammers sont en accord avec python pour les programmeurs. Comme S. Lott dit ci-dessus, ces types de contrôles ne protègent pas contre la logique de bogues, de ne pas réduire le nombre de tests unitaires, vous devez écrire et nous sommes aussi pas de grands fans de la servitude de la programmation.

Voici une liste de ce qui "use strict" ne ne:

  1. À l'aide de références symboliques est une erreur d'exécution. Cela vous empêche de faire des folies (mais parfois des choses utiles comme)

    $var = 'foo';

    $foo = 'bar';

    print $$var; # this would contain the contents of $foo unless run under strict

  2. À l'aide de variables non déclarées est une erreur d'exécution (ce qui signifie que vous devrez utiliser "ma", "notre" ou "local" pour déclarer votre variable du champ d'application avant de l'utiliser.

  3. Tous les barewords sont considérés au moment de la compilation les erreurs de syntaxe. Barewords sont des mots qui n'ont pas été déclarées comme des symboles ou des sous-routines. C'est principalement pour interdire quelque chose qui a toujours été fait, mais est considérée comme ayant été une erreur.

5voto

Leon Timmermans Points 23230

Python n'a pas de véritable portée lexicale, donc les variables strictes ne seraient pas très raisonnables. Il n'a pas de références symboliques AFAIK, il n'a donc pas besoin de références strictes. Il n'a pas de mots nus, il n'a donc pas besoin de variables strictes.

Pour être honnête, ce n'est que la portée lexicale qui me manque. Les deux autres, je considérerais les verrues en Perl.

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