Python PEP 8: le regole sui nomi e lo snake_case per variabili e funzioni

PEP 8 dice che i nomi di funzioni e variabili devono essere in minuscolo, con le parole separate da trattini bassi quando serve alla leggibilità. È lo snake_case: total_price, send_invoice(). Le classi usano CapWords (InvoiceSender), le costanti usano le maiuscole con i trattini bassi (MAX_RETRIES) e i moduli hanno nomi brevi, tutti in minuscolo. Con questo copri la maggior parte del Python che scriverai.
Il resto della sezione di PEP 8 sui nomi è dove stanno i dettagli utili: che cosa significano i trattini bassi iniziali e finali, come trattare le sigle, quali lettere singole evitare e quando infrangere le regole è la scelta giusta. Tutto ciò che segue è verificato su PEP 8 stesso, e ciò che sta tra virgolette è la formulazione originale di PEP 8, in inglese, con la traduzione tra parentesi.
Le convenzioni di PEP 8 sui nomi in sintesi
| Che cosa stai nominando | Stile PEP 8 | Esempio |
|---|---|---|
| Modulo | Breve, tutto minuscolo; trattini bassi se aiutano | billing.py, tax_rules.py |
| Pacchetto | Breve, tutto minuscolo; trattini bassi sconsigliati | payments |
| Classe | CapWords | InvoiceSender |
| Eccezione | CapWords, con suffisso Error se è un errore | PaymentDeclinedError |
| Funzione, metodo | snake_case | send_invoice() |
| Variabile, variabile d'istanza | snake_case | total_price |
| Primo argomento di un metodo | self, oppure cls per i metodi di classe | def from_settings(cls, settings) |
| Costante | Maiuscole con trattini bassi, di solito a livello di modulo | MAX_RETRIES |
| Variabile di tipo | CapWords breve | T, AnyStr |
| Nome non pubblico | Un trattino basso iniziale | _rate_cache |
Ecco la maggior parte della tabella in un piccolo modulo:
# billing.py
MAX_RETRIES = 3
_rate_cache = {}
class PaymentDeclinedError(Exception):
pass
class InvoiceSender:
def __init__(self, smtp_host):
self.smtp_host = smtp_host
self._attempts = 0
def send_invoice(self, invoice_id):
self._attempts += 1
...
@classmethod
def from_settings(cls, settings):
return cls(settings["smtp_host"])Vale la pena conoscere altre due righe, più rare. Le variabili di tipo possono prendere il suffisso _co o _contra per indicare covarianza o controvarianza, come in VT_co = TypeVar('VT_co', covariant=True). E le variabili globali seguono le regole delle funzioni; se un modulo è pensato per essere usato con from module import *, PEP 8 consiglia di elencare i suoi nomi pubblici in __all__.
Perché proprio lo snake_case?
PEP 8 risale al luglio 2001 e i suoi autori indicati sono Guido van Rossum, Barry Warsaw e Alyssa Coghlan. Il punto di partenza è un'osservazione di Guido: il codice si legge molto più spesso di quanto si scriva. Le regole sui nomi servono a questo scopo. I trattini bassi mantengono visibili i confini tra le parole anche nei nomi lunghi (days_since_last_login), e la distinzione tra valori in snake_case e classi in CapWords ti dice che genere di cosa è un nome prima ancora di andarlo a cercare. PEP 8 fissa anche un principio prevalente per le API pubbliche: i nomi dovrebbero riflettere come qualcosa viene usato, non come è implementato.
Che cosa significano i trattini bassi
Python non ha una parola chiave private, quindi a fare quel lavoro sono i trattini bassi, per convenzione. PEP 8 riconosce quattro forme:
_single_leading: un debole segnale di “internal use” (uso interno).from module import *salta questi nomi, ma nient'altro impedisce a qualcuno di usarli.single_trailing_: evita un conflitto con una parola chiave.class_è meglio diclss, anche se PEP 8 osserva che un sinonimo può essere ancora meglio.__double_leading: dentro una classe fa scattare il name mangling. PEP 8 lo suggerisce solo per evitare conflitti con gli attributi nelle sottoclassi, e ammette che a qualcuno non piace.__double_leading_and_trailing__: nomi “magic” (magici) come__init__e__file__. PEP 8 dice di non inventarne mai; usa solo quelli documentati.
Il name mangling sorprende chi lo scambia per una protezione. È una ridenominazione, non un lucchetto:
class Account:
def __init__(self):
self.__pin = "1234"
acct = Account()
acct.__pin # AttributeError
acct._Account__pin # "1234": the mangled name still worksLe costanti sono una convenzione, non una regola
Scrivere un nome in maiuscolo non impedisce a nessuno di riassegnarlo; Python eseguirà tranquillamente MAX_RETRIES = 4. Se vuoi che a farlo rispettare sia uno strumento, annota il nome con typing.Final:
from typing import Final
MAX_RETRIES: Final = 3
MAX_RETRIES = 4 # still runs, but mypy reports:
# Cannot assign to final name "MAX_RETRIES"I membri di un enum sono l'altro posto in cui compaiono le maiuscole. L'HOWTO sugli enum della documentazione di Python raccomanda caldamente nomi di membri in UPPER_CASE, in parte perché gli enum rappresentano costanti e in parte per evitare conflitti con i nomi dei metodi: class Color(Enum) con i membri RED e GREEN.
Sigle, lettere singole e altri casi limite
Le sigle nei nomi delle classi
PEP 8 dice di scrivere in maiuscolo ogni lettera di una sigla in CapWords, quindi HTTPServerError è meglio di HttpServerError. La libreria standard lo segue in punti come http.server.HTTPServer e json.JSONDecodeError. In snake_case le sigle vanno semplicemente in minuscolo: parse_json, http_status.
Conta se rinomini con uno strumento. Il nostro convertitore di maiuscole/minuscole trasforma processOrder in process_order e HTTPServerError in http_server_error, che per lo snake_case è esattamente giusto. Ma il suo output in PascalCase scrive le sigle come parole, quindi HTTP server error diventa HttpServerError, e le maiuscole le correggi a mano per adeguarti a PEP 8.
Lettere da evitare
Non usare mai l (L minuscola), O (o maiuscola) o I (i maiuscola) come nomi di un solo carattere. In alcuni font sono indistinguibili da 1 e 0.
mixedCase
I nomi di funzione in camelCase sono ammessi solo dove quello è già lo stile prevalente, per retrocompatibilità. L'esempio di PEP 8 è il modulo threading.
Perché la libreria standard infrange le sue stesse regole
PEP 8 ammette che i nomi nella libreria di Python siano “a bit of a mess” (un po' un pasticcio). Incontrerai logging.getLogger() e assertEqual() di unittest in mixedCase, e classi in minuscolo come datetime.datetime. I tipi built-in come list e dict sono in minuscolo di proposito: PEP 8 descrive una convenzione a parte per i built-in, con CapWords usato solo per i nomi delle eccezioni e per le costanti built-in.
Due regole di PEP 8 spiegano perché questi nomi per lo più restano come sono. Primo, dove una libreria esistente ha uno stile diverso, si preferisce la coerenza interna. Secondo, la sezione intitolata “A Foolish Consistency is the Hobgoblin of Little Minds” (una stolta coerenza è il folletto delle menti piccole): la coerenza con PEP 8 conta, la coerenza dentro un progetto conta di più e la coerenza dentro un modulo o una funzione conta più di tutte. Non rompere la retrocompatibilità solo per adeguarti. Per questo una classe di test di unittest definisce ancora setUp(): il framework chiama proprio quel nome.
Controlla i nomi in automatico con Ruff o pep8-naming
Non serve rivedere i nomi a occhio. Il plugin di flake8 pep8-naming li controlla, e Ruff implementa gli stessi controlli come regole N. Dato questo file:
maxRetries = 3
class order_processor:
def processOrder(self, orderId):
totalPrice = 0
return totalPrice
class InvalidOrder(Exception):
passRuff segnala ogni nome al suo interno:
$ ruff check --select N --output-format concise orders.py
orders.py:1:1: N816 Variable `maxRetries` in global scope should not be mixedCase
orders.py:4:7: N801 Class name `order_processor` should use CapWords convention
orders.py:5:9: N802 Function name `processOrder` should be lowercase
orders.py:5:28: N803 Argument name `orderId` should be lowercase
orders.py:6:9: N806 Variable `totalPrice` in function should be lowercase
orders.py:10:7: N818 Exception name `InvalidOrder` should be named with an Error suffix
Found 6 errors.Per attivare le regole su un intero progetto, aggiungile a pyproject.toml:
[tool.ruff.lint]
extend-select = ["N"]Quando rinomini un solo identificatore in un file incollato, il nostro strumento Trova e sostituisci mostra quante corrispondenze ha modificato, un controllo rapido prima di incollare di nuovo il risultato. Per un'intera base di codice usa invece il refactoring di rinomina del tuo editor, così i riferimenti negli altri file lo seguono.
Una checklist PEP 8 per i nomi
- snake_case per funzioni, metodi, variabili e argomenti.
- CapWords per le classi, con le sigle in maiuscolo e il suffisso
Errorsulle eccezioni. - Maiuscole con trattini bassi per le costanti a livello di modulo, più
Finalse vuoi che a farle rispettare sia un controllo automatico. - Nomi di modulo brevi e in minuscolo; evita i trattini bassi nei nomi dei pacchetti.
- Un trattino basso iniziale per i nomi interni; doppi trattini bassi solo per evitare conflitti con le sottoclassi.
- Quando una libreria esistente usa un altro stile, adeguati alla libreria.
Passi da un linguaggio all'altro? La nostra guida rapida per sviluppatori mette a confronto le regole di Python con quelle di JavaScript, Java, Go, Rust e altri.


