← Blog · · ConvertCaseHQ-team · 7 min lezen

Python PEP 8-naamgeving: snake_case voor variabelen en functies

PEP 8 zegt dat namen van functies en variabelen uit kleine letters moeten bestaan, met underscores tussen de woorden waar dat de leesbaarheid helpt. Dat is snake_case: total_price, send_invoice(). Klassen gebruiken CapWords (InvoiceSender), constanten gebruiken hoofdletters met underscores (MAX_RETRIES) en modules krijgen korte namen in alleen kleine letters. Daarmee dek je het meeste Python dat je schrijft.

De rest van het naamgevingsdeel van PEP 8 is waar de nuttige details zitten: wat underscores vooraan en achteraan betekenen, hoe je met afkortingen omgaat, welke losse letters je moet vermijden en wanneer het goed is de regels te breken. Alles hieronder is gecontroleerd aan de hand van PEP 8 zelf, en alles wat tussen aanhalingstekens staat, is de eigen formulering van PEP 8.

De naamgevingsconventies van PEP 8 in één oogopslag

Wat je een naam geeftPEP 8-stijlVoorbeeld
ModuleKort, alleen kleine letters; underscores als ze helpenbilling.py, tax_rules.py
PackageKort, alleen kleine letters; underscores afgeradenpayments
KlasseCapWordsInvoiceSender
ExceptionCapWords, eindigend op Error als het een fout isPaymentDeclinedError
Functie, methodesnake_casesend_invoice()
Variabele, instantievariabelesnake_casetotal_price
Eerste argument van een methodeself, of cls bij klassemethodendef from_settings(cls, settings)
ConstanteHoofdletters met underscores, meestal op moduleniveauMAX_RETRIES
TypevariabeleKorte CapWordsT, AnyStr
Niet-publieke naamEén underscore vooraan_rate_cache

Hier zie je het meeste uit de tabel in één kleine module:

# 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"])

Twee zeldzamere regels zijn het weten waard. Typevariabelen kunnen een suffix _co of _contra krijgen om covariantie of contravariantie aan te geven, zoals in VT_co = TypeVar('VT_co', covariant=True). En globale variabelen volgen de regels voor functies; is een module bedoeld om met from module import * te worden gebruikt, dan raadt PEP 8 aan de publieke namen op te sommen in __all__.

Waarom eigenlijk snake_case?

PEP 8 stamt uit juli 2001 en als auteurs staan Guido van Rossum, Barry Warsaw en Alyssa Coghlan vermeld. Het uitgangspunt is een observatie van Guido: code wordt veel vaker gelezen dan geschreven. De naamgevingsregels dienen dat doel. Underscores houden woordgrenzen zichtbaar, zelfs in lange namen (days_since_last_login), en het onderscheid tussen waarden in snake_case en klassen in CapWords vertelt je wat voor soort ding een naam is voordat je hem opzoekt. PEP 8 stelt ook een overkoepelend principe voor publieke API's: namen moeten weergeven hoe iets wordt gebruikt, niet hoe het is geïmplementeerd.

Wat de underscores betekenen

Python kent geen sleutelwoord private, dus underscores doen dat werk bij conventie. PEP 8 onderscheidt vier vormen:

  • _single_leading: een zwakke aanduiding van “internal use” (intern gebruik). from module import * slaat deze namen over, maar verder houdt niets iemand tegen ze te gebruiken.
  • single_trailing_: voorkomt een botsing met een sleutelwoord. class_ is beter dan clss, al merkt PEP 8 op dat een synoniem nog beter kan zijn.
  • __double_leading: binnen een klasse zet dit name mangling in gang (de naam wordt automatisch hernoemd). PEP 8 stelt het alleen voor om botsingen met attributen in subklassen te vermijden en geeft toe dat sommige mensen er een hekel aan hebben.
  • __double_leading_and_trailing__: “magic”-namen zoals __init__ en __file__. PEP 8 zegt dat je ze nooit zelf moet verzinnen; gebruik alleen de gedocumenteerde.

Name mangling verrast mensen die het als privacy beschouwen. Het is een hernoeming, geen slot:

class Account:
    def __init__(self):
        self.__pin = "1234"

acct = Account()
acct.__pin            # AttributeError
acct._Account__pin    # "1234": the mangled name still works

Constanten zijn een conventie, geen regel

Een naam in hoofdletters schrijven houdt niemand tegen hem opnieuw toe te wijzen; Python voert MAX_RETRIES = 4 gewoon uit. Wil je dat een tool het afdwingt, annoteer de naam dan met 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"

Enum-leden zijn de andere plek waar hoofdletters voorkomen. De enum-HOWTO van de Python-documentatie raadt sterk namen in UPPER_CASE voor leden aan, deels omdat enums constanten voorstellen en deels om botsingen met methodenamen te voorkomen: class Color(Enum) met de leden RED en GREEN.

Afkortingen, losse letters en andere randgevallen

Afkortingen in klassenamen

PEP 8 zegt dat je in CapWords elke letter van een afkorting met een hoofdletter schrijft, dus HTTPServerError is beter dan HttpServerError. De standaardbibliotheek volgt dat op sommige plekken, zoals http.server.HTTPServer en json.JSONDecodeError. In snake_case worden afkortingen gewoon kleine letters: parse_json, http_status.

Dat doet ertoe als je met een tool hernoemt. Onze hoofdletter-converter maakt van processOrder een process_order en van HTTPServerError een http_server_error, wat voor snake_case precies klopt. Maar zijn PascalCase-uitvoer schrijft afkortingen als woorden, dus HTTP server error wordt HttpServerError, en de hoofdletters corrigeer je met de hand om bij PEP 8 te passen.

Letters om te vermijden

Gebruik nooit l (kleine L), O (hoofdletter o) of I (hoofdletter i) als naam van één teken. In sommige lettertypen zijn ze niet te onderscheiden van 1 en 0.

mixedCase

Functienamen in camelCase zijn alleen toegestaan waar dat al de heersende stijl is, voor achterwaartse compatibiliteit. Het eigen voorbeeld van PEP 8 is de module threading.

Waarom de standaardbibliotheek zijn eigen regels breekt

PEP 8 geeft toe dat de naamgeving in de bibliotheek van Python “a bit of a mess” is (een beetje een rommeltje). Je komt logging.getLogger() en assertEqual() van unittest tegen in mixedCase, en klassen in kleine letters zoals datetime.datetime. Ingebouwde typen als list en dict zijn bewust in kleine letters: PEP 8 beschrijft een aparte conventie voor ingebouwde namen, waarbij CapWords alleen wordt gebruikt voor namen van exceptions en ingebouwde constanten.

Twee regels uit PEP 8 verklaren waarom deze namen grotendeels blijven zoals ze zijn. Ten eerste: heeft een bestaande bibliotheek een andere stijl, dan gaat interne consistentie voor. Ten tweede het onderdeel met de titel “A Foolish Consistency is the Hobgoblin of Little Minds” (een dwaze consistentie is de boeman van kleine geesten): consistentie met PEP 8 telt, consistentie binnen een project telt meer en consistentie binnen een module of functie telt het meest. Breek de achterwaartse compatibiliteit niet alleen om je aan de regels te houden. Daarom definieert een testklasse van unittest nog steeds setUp(): het framework roept precies die naam aan.

Namen automatisch controleren met Ruff of pep8-naming

Je hoeft namen niet met het oog te controleren. De flake8-plug-in pep8-naming doet dat, en Ruff voert dezelfde controles uit met zijn N-regels. Neem dit bestand:

maxRetries = 3


class order_processor:
    def processOrder(self, orderId):
        totalPrice = 0
        return totalPrice


class InvalidOrder(Exception):
    pass

Ruff markeert elke naam erin:

$ 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.

Om de regels voor een heel project aan te zetten, voeg je ze toe aan pyproject.toml:

[tool.ruff.lint]
extend-select = ["N"]

Hernoem je één identifier via een geplakt bestand, dan laat onze tool Zoeken & vervangen zien hoeveel overeenkomsten hij heeft gewijzigd, een snelle controle voordat je het resultaat terugplakt. Gebruik voor een hele codebase liever de hernoemfunctie (rename refactoring) van je editor, zodat verwijzingen in andere bestanden meekomen.

Checklist voor PEP 8-naamgeving

  • snake_case voor functies, methoden, variabelen en argumenten.
  • CapWords voor klassen, met afkortingen in hoofdletters en een suffix Error op exceptions.
  • Hoofdletters met underscores voor constanten op moduleniveau, plus Final als je wilt dat een checker ze afdwingt.
  • Korte modulenamen in kleine letters; vermijd underscores in namen van packages.
  • Eén underscore vooraan voor interne namen; dubbele underscores alleen om botsingen met subklassen te voorkomen.
  • Gebruikt een bestaande bibliotheek een andere stijl, volg dan de bibliotheek.

Wissel je tussen talen? Ons spiekbriefje voor ontwikkelaars zet de regels van Python naast die van JavaScript, Java, Go, Rust en andere.

© 2026 ConvertCaseHQ. Alle rechten voorbehouden.