Je n'aime pas les répétitions. Je pense que le principe "DRY", "Don't Repeat Yourself", est un principe clé de la programmation. Par conséquent, j'ai effectivement utilisé locals()
dans des situations similaires. Le rendu des modèles de Django est loin d'être la seule situation de ce type : le cas général est " une fonction ou un opérateur qui accepte un dict, mais qui ne se soucie pas que le dict contienne des entrées supplémentaires ". (Par exemple, le formatage ordinaire des chaînes de caractères en Python est un autre cas de ce genre).
Cependant, il existe un principe opposé : les programmes devraient être compréhensibles d'une manière aussi localisée que possible -- cela facilite la maintenance et le remaniement (car cela évite d'avoir à étudier d'autres fichiers pour vérifier quels remaniements sont acceptables). Cela suggère, pour le locals()
que c'est OK si le modèle (ou le format de chaîne de caractères, etc.) est un littéral local (un cas rare où seules quelques variables sont probablement utilisées et où, par conséquent, le format de chaîne de caractères n'est pas utilisé). locals()
n'est pas une victoire énorme !-), mais problématique dans le cas normal où le modèle se trouve dans un fichier différent.
Ainsi, en utilisant locals()
dans la plupart des cas, cela entrave sérieusement le remaniement. Dans presque toutes les situations en Python, les variables locales et leurs noms peuvent être librement modifiés dans le cadre d'un remaniement local, puisqu'ils n'ont pas d'effet "visible de l'extérieur"... mais l'utilisation de la fonction locals()
casse cela -- soudainement vous ne pouvez plus renommer une variable avec un nom différent offrant une meilleure clarté, refactoriser le flux de code d'une manière qui supprime le besoin d'une variable, etc, etc, sans étudier à chaque fois un fichier template séparé pour vérifier si l'ancien nom pourrait ne pas être nécessaire (et éventuellement éditer le fichier template, ce qui peut être non trivial, par exemple s'il est maintenu dans plusieurs langues naturelles différentes pour des raisons d'i18n/L10n).
Par conséquent, en plus de la question secondaire de la performance, il existe une forte pression. contre en utilisant locals()
dans un code "sérieux", "de production" -- un code qui nécessite une maintenance à long terme et donc un remaniement et une localisation faciles. Ainsi, lorsque je "programme du mieux que je peux", plutôt que de "faire des économies", je suis conscient que je dois éviter de locals()
.
Les valeurs que vous voulez avoir dans le contexte dans lequel le modèle est rendu ne sont pas nécessairement "naturellement" disponibles sous forme de noms nus locaux, après tout ; peut-être que certaines ou beaucoup d'entre elles sont des résultats de calculs, des éléments de listes ou de dictionnaires, et ainsi de suite. Dans ce cas, la tentation de "couper les coins ronds" avec des noms nus est grande. locals()
est plus facile à éviter si vous accumulez ces valeurs dans un dictionnaire approprié plutôt que de leur attribuer des noms locaux nus.
Ce n'est pas le compromis le plus facile, car deux bons principes (éviter la répétition et avoir une bonne localité) s'opposent inévitablement - donc, bonne question ! Et ce n'est pas une question qui se prête à des réponses tranchées, noires ou blanches, c'est pourquoi j'ai essayé de développer les deux côtés. En fin de compte, je pense que c'est l'un de ces aspects de "style" où une équipe de programmation serait bien avisée d'adopter une directive de style uniforme pour l'équipe et de s'y tenir -- au moins, cela supprime le besoin de prendre une décision encore et encore chaque fois que le problème se pose, et produit une base de code plus homogène (et donc maintenable). [[Je dois avouer que ce point spécifique n'a jamais été explicitement abordé dans les directives de style des équipes auxquelles j'ai participé, bien que beaucoup d'autres l'aient fait!-)]].