Devrais-je vraiment utiliser toutes les majuscules pour mes constantes?

34

Je suis principalement un programmeur Python qui utilise pylint pour imbriquer le code source. Je suis en mesure d'éliminer tous les avertissements sauf un: Nom non valide pour une constante. Changer le nom en majuscule le corrige, mais suis-je vraiment supposé faire cela? Si je le fais, je trouve que mon code a l'air laid, car la plupart des variables sont constantes (selon pylint).

Abhishek Kumar
la source
2
Si la plupart de vos variables sont des constantes au niveau du module, vous faites probablement quelque chose d'inhabituel. La plupart d'entre eux devraient vivre à l'intérieur de fonctions.
RemcoGerlich
1
Pouvez-vous nous montrer un échantillon de votre code que pylint pense être des constantes?
Winston Ewert
@ WinstonEwertNOTES_DIRECTORY = argv[1] chdir(NOTES_DIRECTORY) FILES = glob('*.txt') RAND_FILE = choice(FILES) with open(RAND_FILE) as notes_file: POINTS = notes_file.readlines() RAND_POINT = choice(POINTS)
Abhishek Kumar
@AbhishekKumar, votre code est-il dans une fonction ou au plus haut niveau?
Winston Ewert
@ WinstonEwert Au plus haut niveau et après avoir suivi les instructions de PyLint.
Abhishek Kumar

Réponses:

33

Vous écrivez probablement un code comme celui-ci:

notes_director = argv[1]
chdir(notes_director)
files = glob('*.txt')
rand_file = choice(files)
with open(rand_file) as notes_file: 
    points = notes_file.readlines() 
    rand_point = choice(points)

Vous devriez déplacer ce code dans une fonction:

def main():
    notes_director = argv[1]
    chdir(notes_director)
    files = glob('*.txt')
    rand_file = choice(files)
    with open(rand_file) as notes_file: 
        points = notes_file.readlines() 
        rand_point = choice(points)

# actually call the main function    
main()

Pylint suppose que le code qui fait le travail sera à l'intérieur d'une fonction. Parce que vous avez ce code au plus haut niveau de votre code plutôt que dans une fonction, cela devient confus.

De manière générale, il est préférable de travailler dans une fonction plutôt qu'au niveau supérieur. Cela vous permet de mieux organiser ce que vous faites et facilite sa réutilisation. Vous devriez vraiment avoir du code exécutant un algorithme en dehors d'une fonction dans un script rapide et sale.

Winston Ewert
la source
1
Fortement en désaccord, je pense qu’il existe de nombreuses bonnes raisons pour Pythonic d’utiliser des variables de niveau module. Je pense que ce conseil est simplement un artefact de PEP8 mal interprété par pylint, et en supposant que l'inverse de "les constantes devraient être au niveau du module" devrait également être vrai.
MetricSystem
21

Oui. Selon la règle PEP8 sur les constantes :

Les constantes sont généralement définies au niveau du module et écrites en majuscules avec des tirets bas séparant les mots. Les exemples incluent MAX_OVERFLOWet TOTAL.

Version longue:

Dans la communauté Python (comme dans beaucoup d'autres communautés), il existe des conventions sur la manière d'écrire du code. Cela diffère du code de travail : même si vous écrivez vos constantes en minuscules, votre code fonctionne toujours.

Mais il existe un consensus communautaire (comme documenté dans PEP8) qui est "appliqué" avec des outils tels que pylint . Si vous programmez pour votre propre bonheur, vous risquez de négliger les allusions que vous donne Pylint. Si vous souhaitez un échange ouvert avec la communauté, autrement dit "quelqu'un d'autre que moi doit utiliser mon code", vous devez préparer votre code conformément à PEP8.

Thomas Junk
la source
7
D'autre part, il est tout à fait possible pylintde se tromper. Python ne permet pas de distinguer une constante d'une variable, sinon que la constante doit toujours avoir la même valeur. pylintsuppose que tout ce qui n'est défini qu'une fois et qui ne change jamais est une constante, mais à moins que ce ne soit censé être une constante, cela pourrait simplement être un artefact de la mise en œuvre. Et plus précisément, le code donné dans le commentaire de la question contient des valeurs qui seront différentes à chaque exécution. Par conséquent, vous ne devez pas les considérer comme des constantes, même si pylint pense qu'elles le sont.
Jules
@Jules J'appellerais les variables définies une fois et ne changeant jamais, au cours de l'exécution, comme une constante; il existe donc dans de nombreuses langues (par exemple en JS) un constmot clé. Bien que la valeur initiale soit différente, à part peut-être PI.
Thomas Junk
1
Je ferais la distinction entre une variable immuable (c'est-à-dire quelque chose qui est défini au moment de l'exécution et non modifié) et une constante (c'est-à-dire quelque chose qui est identique dans chaque programme exécuté, et si le langage le permet, il peut être calculé au moment de la compilation. ) ... le fait est que, faute de moyen de spécifier la distinction entre python, pylintsupposons le dernier, même lorsque le premier est le cas.
Jules
Pylint a tout à fait tort, en ce sens qu'il lit "les constantes doivent être au niveau du module" et suppose l'inverse "le niveau du module doit être des constantes". Mais comme c’est un autre outil utile, il semble que nous nous en tenons à cela.
MetricSystem
@MetricSystem Quelle fonction aurait, à votre avis, une variable de niveau module en plus d'être une constante? Devrait-il être mutable?
Thomas Junk
13

La norme de communauté PEP8 et Python est à utiliser ALL_CAPS_CONSTANTS. C'est un indice visuel commun, utilisé depuis des décennies en C, Java, Perl, PHP, Python, bash et autres langages de programmation et environnements shell. Mais dans le langage en ligne moderne, TOUS LES CAPS SIGNIFIE CRIENT . Et crier est impoli.

Python est cependant plutôt incohérent ALL_CAPS_CONSTANTS. JavaScript peut avoir Math.PI, mais Python a math.pi. Il n'y a pas de constante plus reconnaissable ou durable que π. Ou considérez sys.version_infola version de Python que vous utilisez. 100% constant sur la durée de votre programme - bien plus que PORTou MAX_ITERATIONSou d'autres constantes que vous définiriez. Ou à propos sys.maxsize? La valeur entière maximale de votre plate-forme est constante non pas sur un ou deux programmes, mais sur la durée de vie de votre matériel.

Si ces constantes - y compris certaines comme π et e qui sont des constantes fondamentales de l'univers et ne varieront pas au cours de toute l'éternité - si elles peuvent être en minuscule, eh bien ... les autres constantes le peuvent aussi. Tu peux choisir.

Rappelez-vous que PEP8 est un guide de style. Une ligne directrice, pas une loi. Une directive souvent enfreinte, même par la bibliothèque standard de Python. Et citant une autre directive de base de Python, PEP20 (alias "Le zen de Python"):

  • Beau vaut mieux que moche
  • La lisibilité compte
  • La praticité bat la pureté.

Sur le plan pratique, lorsqu'un programme de YELLY_CONSTANTet SHOUTY_PARAMETERcommence à râper, il aide à se rappeler que les constantes en majuscules ne sont généralement pas vraiment enduraient idéaux platoniciens , mais les paramètres d'une exécution du programme. Il n’ya rien de vraiment constant à propos de PORT, SITENAMEet NUMRUNS, et ils ne doivent pas être gérés comme des programmes globaux autonomes. Par exemple, ils peuvent être déposés dans un dictionnaire sous la forme d'un ensemble de paramètres de programme accessible de manière globale:

config = {
    'port': 80,
    'sitename': "Bubba's Blog",
    'numruns': 100,
}

Python dispose également d’une fonctionnalité de passage de paramètres par mot clé fine qui réduit le besoin d’utiliser APPARENTLY_ANGRY_GLOBAL_VARIABLES:

def process_data(sitename, port=80, numruns=100):
    ...

process_data("Bubba's Blog")

En pratique, beaucoup de ces valeurs seront (ou devraient être) lues à partir de fichiers de configuration, de variables d’environnement de système d’exploitation, d’arguments de ligne de commande ou d’autres sources pour satisfaire l’ inversion du principe / modèle de contrôle . Mais c'est une histoire plus large pour un autre jour.

Jonathan Eunice
la source
1

Oui, c'est assez courant dans la plupart des langages de programmation (du moins ceux que j'utilise).

Vous pouvez vous référer à ce lien Google pour partager un style commun entre les développeurs de la même équipe.

Il est conseillé d'utiliser

Type                  |Public          |Internal
Global/Class Constants|CAPS_WITH_UNDER |_CAPS_WITH_UNDER
alain.janinm
la source