Dovrei davvero usare tutte le maiuscole per le mie costanti?


34

Sono un programmatore Python principalmente che usa pylint per il codice sorgente di sfilacciamento. Sono in grado di eliminare tutti gli avvisi tranne uno: Nome non valido per una costante. Cambiare il nome in maiuscolo lo risolve, ma dovrei davvero farlo? Se lo faccio, trovo che il mio codice sembri brutto poiché la maggior parte delle variabili sono costanti (secondo il pilastro).


2
Se la maggior parte delle variabili sono costanti a livello di modulo, probabilmente stai facendo qualcosa di insolito. La maggior parte di loro dovrebbe vivere all'interno di funzioni.
RemcoGerlich,

1
puoi mostrarci un esempio del tuo codice che Pylint pensa siano costanti?
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, il tuo codice è in una funzione o al livello più alto?
Winston Ewert,

@WinstonEwert Al livello più alto e dopo aver seguito le istruzioni di PyLint.
Abhishek Kumar,

Risposte:


33

Probabilmente stai scrivendo codice in questo modo:

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)

È necessario spostare questo codice in una funzione:

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 presuppone che il codice che svolge effettivamente il lavoro si troverà all'interno di una funzione. Poiché hai questo codice al livello più alto del tuo codice anziché all'interno di una funzione, viene confuso.

In generale, è meglio lavorare all'interno di una funzione anziché al livello più alto. Ciò ti consente di organizzare meglio ciò che stai facendo e facilita il riutilizzo. Dovresti davvero avere codice che esegue un algoritmo al di fuori di una funzione in uno script veloce e sporco.


1
Non sono affatto d'accordo, penso che ci siano molte buone ragioni Pythonic per usare le variabili a livello di modulo. Penso che questo consiglio sia semplicemente un artefatto di pylint che fraintende PEP8, e supponendo che il contrario di "costanti dovrebbe essere a livello di modulo" dovrebbe anche essere vero.
MetricSystem

21

Sì. Secondo la norma PEP8 sulle costanti :

Le costanti sono generalmente definite a livello di modulo e scritte in lettere maiuscole con caratteri di sottolineatura che separano. Gli esempi includono MAX_OVERFLOWe TOTAL.

Versione lunga:

Nella comunità Python (come in molte altre comunità) esistono convenzioni su come scrivere codice. Questo è diverso dal codice di lavoro : anche se scrivi le tue costanti tutte in minuscolo, il tuo codice funziona ancora.

Ma c'è consenso della comunità (come documentato in PEP8) che viene "applicato" con strumenti come il pylint . Se programmi per la tua felicità, potresti trascurare i suggerimenti che la colonna sonora ti dà. Se vuoi uno scambio aperto con la community, noto anche come "qualcuno oltre a me stesso dovrebbe usare il mio codice", dovresti preparare il tuo codice secondo PEP8.


7
D'altra parte, è del tutto possibile pylintsbagliare. Python non fornisce un modo per distinguere una costante da una variabile, a parte il fatto che la costante dovrebbe avere sempre lo stesso valore. pylintpresuppone che tutto ciò che viene impostato una sola volta e non cambi mai sia una costante, ma a meno che non sia inteso come una costante, potrebbe essere solo un artefatto dell'implementazione. E in particolare il codice fornito nel commento alla domanda ha valori che saranno diversi su ogni esecuzione, quindi non dovrebbero essere considerati costanti anche se il pylint pensa di esserlo.
Jules,

@Jules Vorrei chiamare le variabili impostate una volta e cambiando durante il runtime mai più una costante, quindi esiste in molte lingue (ad esempio in JS) una constparola chiave. Sebbene il valore iniziale sia diverso, forse diverso PI.
Thomas Junk,

1
Distinguerei tra una variabile immutabile (ovvero qualcosa che è impostato in fase di runtime e non è cambiato) e una costante (cioè qualcosa che è la stessa in ogni programma eseguito, e se la lingua fornisce l'opzione per farlo potrebbe essere calcolata al momento della compilazione ) ... il punto è che, poiché manca un modo per specificare la distinzione con Python, si pylintassume la seconda ipotesi anche quando la prima è il caso.
Jules

Pylint ha sicuramente torto, in quanto legge "le costanti dovrebbero essere a livello di modulo" e ha ipotizzato che il "livello del modulo dovrebbe essere costante". Ma poiché altrimenti è uno strumento utile, sembra che ci stiamo bloccando.
MetricSystem

@MetricSystem quale funzione - secondo te - avrebbe una variabile a livello di modulo oltre ad essere una costante? Dovrebbe essere mutevole?
Thomas Junk,

13

È necessario utilizzare la norma della comunità PEP8 e Python ALL_CAPS_CONSTANTS. È un indizio visivo comune, usato da decenni in C, Java, Perl, PHP, Python, bash e altri linguaggi di programmazione e ambienti shell. Ma nel moderno linguaggio online, TUTTE LE TAPPETTE SIGNIFICANO LA GRAZIA . E gridare è maleducato.

Python è, tuttavia, piuttosto incoerente ALL_CAPS_CONSTANTS. JavaScript potrebbe avere Math.PI, ma Python ha math.pi. Non esiste una costante più riconoscibile o duratura di π. Oppure considera sys.version_infola versione di Python su cui stai eseguendo. Costante al 100% per tutta la durata del tuo programma - molto più PORTo MAX_ITERATIONSo altre costanti che definiresti. O che ne dici sys.maxsize? Il valore intero nativo massimo della tua piattaforma è costante non solo su uno o due programmi, ma sulla durata del tuo hardware.

Se queste costanti - tra cui alcuni, come π ed e che sono costanti fondamentali dell'universo, e non variano nel tutta l'eternità - se essi possono essere minuscolo, così ... così can altre costanti. Puoi scegliere.

Ricorda, PEP8 è una guida di stile. Una linea guida, non una legge. Una linea guida spesso violata anche dalla libreria standard di Python. E citando un'altra linea guida Python di base, PEP20 (alias "The Zen of Python"):

  • Bello è meglio che brutto
  • La leggibilità conta
  • La praticità batte la purezza.

Da un punto di vista pratico, quando un programma inizia YELLY_CONSTANTe SHOUTY_PARAMETERinizia a grattarsi, aiuta a ricordare che le costanti in maiuscolo generalmente non sopportano realmente gli ideali platonici , ma i parametri di un programma in esecuzione. Non c'è nulla di veramente costante su PORT, SITENAMEo NUMRUNS, e non devono essere gestiti come globali programma autonomo. Ad esempio, possono essere rilasciati in un dizionario come un bundle accessibile a livello globale di parametri del programma:

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

Python ha anche una funzione di passaggio dei parametri di parole chiave che riduce la necessità di usare APPARENTLY_ANGRY_GLOBAL_VARIABLES:

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

process_data("Bubba's Blog")

In pratica, molti di questi valori verranno (o dovrebbero essere) letti da file di configurazione, variabili di ambiente del sistema operativo, argomenti della riga di comando o altre fonti per soddisfare l' inversione del principio / modello di controllo . Ma questa è una storia più grande per un altro giorno.


1

Sì, è abbastanza comune nella maggior parte dei linguaggi di programmazione (almeno quelli che uso).

Puoi fare riferimento a questo link di Google per condividere uno stile comune tra gli sviluppatori dello stesso team.

Si consiglia di utilizzare

Type                  |Public          |Internal
Global/Class Constants|CAPS_WITH_UNDER |_CAPS_WITH_UNDER
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.