Divendres, octubre 17, 2025
PROGRAMACIÓ

Comentaris, estil i primeres bones pràctiques

El codi no s’escriu només per a què funcioni. També s’escriu per a què algú més (inclòs tu dins de tres setmanes) ho entengui. A Python, com a qualsevol llenguatge, la llegibilitat no és opcional. I tot i que black, flake8 o pylint poden ajudar-te a corregir l’estil, l’essencial és saber quines certes decisions fan el codi més clar o més difícil de mantenir.

En aquesta entrada ens centrem a:

  • Com escriure comentaris útils (i què evitar)
  • Triar noms de variables que no molestin
  • Organitzar el codi perquè no sembli un bolcat mental
  • Estil general i convencions que sí que importen
  • Primeres pràctiques d’ escriptura neta que convé adquirir des del principi

1. Comentaris: quan escriure’ls, com escriure’ls i què evitar

Els comentaris a Python (i en qualsevol llenguatge) tenen una funció senzilla: explicar el que el codi no diu per si mateix. El problema és que molta gent els fa servir malament. Alguns comenten tot, fins i tot l’obvi. D’altres no escriuen ni un de sol, confiant que “ja s’entén”. Ambdós extrems causen problemes.

Els comentaris no són per omplir, ni per impressionar. Són per ajudar. Ajudar la persona que vindrà després —i gairebé sempre, aquesta persona ets tu. Un bon comentari dona context, no repeteix el codi. És com un cartell ben posat: breu, clar, al lloc just.

Saber comentar bé no és escriure més, és escriure només quan cal i dir el que de veritat importa.

1.1 Tipus de comentaris

Hi ha tres formes de comentar a Python:

  • Comentari en línia: comença amb #, en la seva pròpia línia o al final d’ una línia de codi.
  • Docstring: una cadena entre triples cometes al principi d’ una funció, classe o mòdul.
  • Comentaris temporals: línies de codi comentades, normalment per a proves. No haurien de quedar en el codi final.

Vegem-los un a un.

1.2 Comentaris en línia

El típic # per a explicar alguna cosa. Útils quan aporten context. Poden anar abans o al costat del codi.

# Convertim la temperatura de Fahrenheit a Celsius
temp_c = (temp_f - 32) * 5 / 9
 
resultat = calcular_preu_final() # inclou impostos i descomptes

Quan fer-los servir:

  • Per a explicar per què fas alguna cosa (no què fas).
  • Per aclarir un ús no evident o evitar confusió.
  • Per assenyalar una limitació o comportament inusual.

Quan evitar-los:

  • Per a repetir el que ja diu el codi.
  • Per a  “narrar” línia per línia.

Exemple real:

# Evitem fer servir get() perquè necessitem llençar excepció si falta
user_id = data["user_id"]

Aquí el comentari justifica una decisió poc evident, que podria semblar un oblit.

1.3 Docstrings: documentació estructurada

Les docstrings són cadenes multilínia que serveixen com a documentació oficial per a funcions, classes i mòduls. A diferència dels comentaris normals, s’hi poden accedir des del codi (help(), .__doc__, generació automàtica de docs, etc).

Exemple de funció amb docstring:

def calcular_preu_total(productes, incloure_enviament =False):
    """
    Calcula el preu total d' una llista de productes.
 
    Args:
        productes (list): Llista de diccionaris amb claus 'preu' i 'quantitat'.
        incloure_enviament (bool): Si es suma el cost de l'enviament al total.
 
    Returns:
        float: Preu total calculat.
    """
    ...

Fer servir docstrings des del començament té diversos avantatges:

  • Ajuda a dissenyar bé una funció (t’obliga a pensar en entrades i sortides).
  • Permet generar documentació automàtica.
  • Millora la comprensió sense necessitat d’ obrir el codi.

Hi ha diversos estils (Google, NumPy, reStructuredText). L’important és ser consistent dins d’un projecte.

1.4 Comentaris temporals i codi comentat

# usuaris = carregar_usuaris_des_de_bd()
usuaris = MOCK_USERS # fer servir dades fixes durant proves

És vàlid durant el desenvolupament, però deixa rastre si no ho neteges. Codi comentat que es “queda per si de cas” es torna brossa tècnica en poc temps.

Regla clara: si està comentat i porta setmanes aquí, esborra’l o fes-ho configurable.

1.5 Què comentar (i què no)

Aquí van decisions pràctiques:

SituacióComentari?Què posar
Fórmules complexes o no òbviesQuè representa i per què es calcula així
Recerques o accessos a estructures de dades complicadesQuè estem buscant i per què
Workarounds, hacks o compatibilitat amb versionsQuina és la limitació i per què es fa així
Comportament inesperat d’una llibreria externaReferència al bug o documentació
Trucades a funcions ben nomenades i autoexplicativesNoEl codi ja ho diu tot
Estructures simples i trivialsNoEvita comentar l’obvi
Codi temporal o desactivatDe vegadesPosen un TODO amb data o issue, o esborra’l

1.6 Comentaris com a marques de tasques

Hi ha convencions per assenyalar coses que estan pendents, trencades o per revisar:

# TODO: reemplaçar aquest mètode quan es migri a la nova API
# FIXME: això falla quan el camp 'data' és None

Aquestes marques poden integrar-se amb editors, linters i sistemes de CI. Però si no les has de  rastrejar, no les posis.

Consell: acompanya-les amb data o autor si han de quedar un temps.

# TODO (miguel, 2025-07-10): eliminar quan s'utilitzi la nova API de factures

1.7 Comentaris vs bon codi

Sovint, el millor comentari és un nom ben posat.

Exemple:

# Comprovem si l'usuari és major d'edat
if edat >= 18:
    ...

És millor això:

es_major_d_edat = edat > = 18
if  es_major_d_edat:
    ...

Noms clars reemplacen molts comentaris innecessaris.

Un altre exemple més clar:

# Calcular ràtio entre aprovats i total
ràtio = aprovats / total_alumnes

Millor així:

percentatge_aprovats = aprovats / total_alumnes

Si el nom expressa la intenció, el comentari sobra.

1.8 Comentaris multilínia (blocs de context)

Quan un bloc de codi depèn d’ una decisió tècnica o negoci complexa, un comentari explicatiu previ pot estalviar molt de temps al següent que llegeixi el codi.

# Si el pagament és per transferència, no podem confirmar automàticament.
# Necessitem que ho validi manualment.
if metode_pagament = = "transferència":
    estat = "pendent_revisió"
else:
    estat = "confirmat"

Aquest tipus de comentari sí que aporta valor: respon al “per què es fa així?”, no només al “què fa?”.

1.9 Comentaris que envelleixen malament

Un problema habitual: comentaris que eren correctes fa mesos, però el codi va canviar i ningú els va actualitzar.

# Fem servir GET perquè l'API no permet POST en aquest endpoint
response = requests.post(url, data=data)

Aquest comentari no només és inútil: és fals. Enganya.

Consell pràctic: si no has de mantenir-lo, no ho posis. De vegades és millor obligar-se a llegir el codi que confiar en comentaris obsolets.

1.10 Revisió de comentaris en code review

Quan fas revisió de codi (propi o aliè), passa sempre per aquests punts:

  • El comentari explica una cosa que el codi no deixa clar?
  • Està actualitzat i és coherent amb el codi real?
  • Podria el comentari eliminar-se si el codi es reescriu millor?
  • Es refereix a comportament real o a intencions passades?

És habitual trobar comentaris tipus:

# Això es va arreglar amb el pegat temporal de juliol
...

Que ja no tenen sentit sis mesos després. Si és història, treu-lo del codi i del changelog, documentació o l’ historial de git.

1.11 Comentaris com a forma de pensar

Un truc útil: quan no tens clar com resoldre alguna cosa, escriu primer el comentari del que vols que passi. Després tradueix-lo a codi.

# Si l'usuari no té comandes, mostrar missatge de benvinguda
if not usuari.comandes:
    mostrar_benvinguda()

Aquesta tècnica pot ajudar-te a escriure codi més expressiu, perquè primer t’obliga a pensar en termes humans.

1.12 Comentaris en altres idiomes

Regla general: escriu els comentaris en l’ idioma que es fa servir en la resta del projecte.

Si és un projecte en anglès, comenta en anglès. Si és personal o local, català està bé. L’important és no barrejar ni escriure comentaris per a un de sol.

2. Noms de variables: clars, sense obsessionar-se

No hi ha res més molest que llegir codi amb variables com a, b, tmp, data1, foo. També és un error l’ extrem contrari: noms larguíssims que repeteixen el context ja donat pel propi nom de la funció o classe.

Exemples de noms dolents

def get_data(d):
    for x in d:
        do_something(x)

Aquí no sabem què és d, ni què és x. Això costa segons extra cada vegada que es llegeix, i s’acumula.

Millors noms

def get_data(entries):
    for entry in entries:
        do_something(entry)

Podem fer-ho encara millor? Depèn de què representa cada cosa:

def get_usernames(users):
    for user in users:
        yield user["username"]

Aquí queda clar què esperem d’users i què retorna la funció.

Bones pràctiques

  • Fes servir noms descriptius, però sense guarniments ni repeticions innecessàries.
  • Si el context ja és evident, no el repeteixis:
# Dolent
def get_user_name_from_user(user):
    return user.name
 
# Millor
def get_user_name(user):
    return user.name
  • Per a bucles simples on el context ho permet, Fer servir i, j o item és acceptable, però no fora de blocs petits.
for i in range(10):  # bé si és un bucle curt
    ...

Si i representa una altra cosa, fes servir un nom més específic.

  • Evita noms tipus data, info, stuff, thing llevat que estiguis fent una cosa realment genèrica.

3. Organització bàsica del codi

Ordre lògic dins d’ un arxiu

Quan algú obre el teu arxiu, hauria de poder veure en segons:

  • Què fa l’ script o mòdul
  • On comença la lògica principal
  • Quines parts són auxiliars

Un ordre típic (en mòduls simples) podria ser:

# imports
import os
import sys
 
# constants
DEFAULT_TIMEOUT = 5
 
# funcions auxiliars
def cargar_configuracion():
    ...
 
def validar_usuario( usuari):
    ...
 
# lògica principal
def main():
    ...
 
if __name__ == "__main__":
    main()

Això ajuda molt a qui arriba de nou a l’arxiu. Si tot està barrejat, cada lectura requereix escanejar tot l’arxiu buscant on comença “l’important”.

Espais i separació

Python és molt sensible als espais (literalment), però també ho és a nivell visual. Fer servir espais en blanc amb intenció millora molt la llegibilitat.

Exemple:

# separa funcions entre si amb una línia
def foo():
    pass
 
def bar():
    pass

Dins d’ una funció, fa servir línies en blanc per marcar blocs lògics diferents:

def processar_dades(entrada):
    dades_filtrades = [d for d in entrada if d > 0]
 
    resultats = []
    for dada in dades_filtrades:
        resultats.append(analitzar(dada))
 
    return resultats

Això ajuda a “llegir” l’estructura encara que no hi hagi comentaris.

4. Convencions d’estil (PEP 8)

Python té una guia d’estil oficial: PEP 8. No cal conèixer-la de memòria, però seguir les seves normes bàsiques fa que el teu codi sigui més fàcil de llegir per a qualsevol que hagi treballat amb Python.

Alguns punts essencials:

4.1. Noms

  • Funcions i variables: snake_case
  • Classes: CamelCase
  • Constants: MAJÚSCULES_AMB_GUIONS
def calcular_preu_final():
    ...
 
class Comanda:
    ...
 
TASA_IVA = 0.21

4.2. Longitud de línia

Evita línies que passin els 79 caràcters. Sí, és antic. Sí, les pantalles són més amples. Però a molts editors, o en fer git diff, les línies llargues es tallen. Escriure pensant en això estalvia molèsties.

4.3. Espais

# Correcte
x = 1
y = x + 2
 
# Incorrecte
x=1
y = x+2

També:

# Correcte
def sumar(a, b):
    return a + b
 
# Incorrecte
def sumar(a,b):
    return a+b

No és per estètica, és perquè en estar tot enganxat costa més llegir-lo.

4.4. Imports

Organitzeu-los així:

  • Mòduls estàndard
  • Mòduls de tercers
  • Mòduls locals

Amb una línia en blanc entre cada grup:

import os
import sys
 
import requests
import numpy as np
 
from .utils import netejar_text

5. Bons hàbits des del començament

Algunes pràctiques que convé adquirir aviat, encara que no siguin obligatòries:

5.1. No repeteixis codi

Si fas alguna cosa més d’una vegada, probablement sigui una funció. Evita copiar i enganxar fragments. El codi duplicat sovint deriva en errors quan es modifica una part però no una altra.

5.2. Fes servir constants en comptes de valors màgics

# Dolent
if status == 3:
    ...
 
# Millor
ESTAT_ACTIU = 3
 
if status == ESTAT_ACTIU:
    ...

Fins i tot en scripts petits, això millora la llegibilitat i prevé errors absurds.

5.3. Evita comentaris tipus “TODO: millorar això” si no penses fer-ho

Els TODO, FIXME i similars només tenen sentit si realment estàs fent servir una eina per a rastrejar-los o has de tornar a aquest codi. Si no, són soroll.

5.4. Escriu pensant a llegir, no a presumir

Evita fer servir trucs del llenguatge només perquè són possibles. Per exemple:

# Massa compacte
return [func(x) for x in items if cond(x)]
 
# Més clar si és complex
resultats = []
for item in items:
    if cond(item):
        resultats.append(func(item))
return resultats

6. Errors comuns

Molts errors d’estil o males pràctiques no venen de la ignorància, sinó de la pressa. El problema és que pagaràs aquest estalvi de temps diverses vegades després, en bugs, confusió o necessitat de reescriptura. Aquí algunes trampes habituals que convé evitar fins i tot en scripts “de prova”.

6.1. Variables genèriques “per ara”

Estàs escrivint una cosa ràpida i fas servir variables com tmp, result, foo, x. Ho has de canviar després, és clar. Però després et distreus, passa el commit, i aquest nom queda per sempre.

tmp = procesar_archivo(archivo)
if tmp:
    for x in tmp:
        if x['id'] == id_actual:
            fer_alguna_cosa(x)

Aquest fragment es torna il·legible molt ràpid. El problema no és tècnic, sinó humà: quan alguna cosa sembla funcionar, costa justificar l’esforç de refactoritzar-lo. Però si el codi no es pot llegir sense pausa, ja és un problema.

6.2. Comprimir tot en una línia “perquè sí”

Python ho permet, però no ajuda.

if user and user.is_active and user.last_login and (now - user.last_login).days < 30:
    send_email(user.email)

¿Funciona? Sí. És còmode de llegir o depurar? No.

Millor així:

if not user:
    return
 
if not user.is_active:
    return
 
if not user.last_login:
    return
 
dies_inactiu = (now - user.last_login).days
if dies_inactiu >= 30:
    return
 
send_email(user.email)

És més llarg, però molt més fàcil d’entendre i mantenir. Aquesta és la diferència entre escriure codi per a màquines o per a humans.

6.3. Comentaris que ja no corresponen al codi

Això passa més sovint del que sembla:

# Aquí filtrem els productes per preu i categoria
productes = filtrar_productes(stock, nomes_disponibles=True)

Aquest comentari ja no reflecteix el que fa la funció. Potser en el passat tenia un filtre més complex, però ara només en queda un. O ha canviat el comportament i no el comentari. És pitjor que no tenir comentari.

Fes neteja periòdica dels comentaris igual que del codi.

6.4. Excés de comentaris perquè el codi és críptic

De vegades veus això:

# Recorre la llista d'usuaris
# Verifica si l'usuari està actiu
# Si està actiu, afegeix el seu email a la llista
for u in usuaris:
    if u.activo:
        llista_emails.append(u.email)

Això no és un comentari útil, és una traducció paraula per paraula. El comentari només caldria si hi hagués alguna cosa no evident:

# Incloem només usuaris actius perquè els inactius ja no reben notificacions
for u in usuaris:
    if u.activo:
        llista_emails.append(u.email)

7. Un petit exemple complet amb bones pràctiques

import os
from datetime import datetime

MAX_ANTIGUITAT_DIES = 30
 
def obtenir_usuaris_actius(usuaris):
    """Retorna una llista amb els emails d’ usuaris actius recents."""
    resultat = []
    ara = datetime.now()
 
    for usuari in usuaris:
        if not usuari.get("actiu"):
            continue
 
        data_ultim_login = usuari.get("ultim_login")
        if not data_ultim_login:
            continue
 
        dies_inactiu = (ara - data_ultim_login).days
        if dies_inactiu > MAX_ANTIGUITAT_DIES:
            continue
 
        resultat.append(usuari["email"])
 
    return resultat
 
def enviar_emails(emails):
    for email in emails:
        print(f"Enviant correu a: {email}")  # en real: fer servir llibrería de correu
 
def main():
    # Això normalment vindria d’ una base de dades o API
    usuaris = [
        {"email": "ana@example.com", "actiu": True, "darrer_login": datetime(2025, 7, 1)},
        {"email": "luis@example.com", "actiu": False, " darrer_login ": datetime(2025, 6, 10)},
        {"email": "mar@example.com", "actiu": True, " darrer_login ": datetime(2025, 5, 15)},
    ]
 
    emails = obtenir_usuaris_actius(usuaris)
    enviar_emails(emails)
 
if __name__ == "__main__":
    main()

Aquest script no fa res complex, però mostra diverses coses ben organitzades:

  • Importacions clares i ordenades.
  • Constant amb nom explícit.
  • Funció amb nom descriptiu, comentari curt i precís.
  • Variables que s’ entenen en llegir.
  • Separació entre lògica de negoci (obtenir_usuaris_actius) i de presentació (enviar_emails).
  • Punt d’entrada (main) net i reconeixible.

8. Eines que ajuden (però no reemplacen el criteri)

8.1. black

Formatejador automàtic. Si el fas servir, respecta PEP8 gairebé al peu de la lletra. Estalvia discussions d’ estil i fa que el codi llueixi uniforme.

black archivo.py

Pots integrar-lo en editors com VSCode o en pre-commits.

8.2. Floc8 / Ruff

Lanter que detecta errors d’ estil i certes males pràctiques. ruff és més ràpid i modern. No està malament executar-lo abans de fer commit.

ruff archivo.py

8.3. pylint

Més estricte i detallat. De vegades excessiu, però configurable.

9. Criteris per decidir entre opcions vàlides

De vegades hi ha més d’una forma correcta d’escriure alguna cosa. Com triar?

  • És llegible sense comentaris? Si necessites explicar massa, reescriu.
  • És consistent amb la resta del projecte? Si tot està en snake_case, no introdueixis camelCase.
  • ¿Facilita el test? Codi més modular, amb funcions petites, es prova millor.
  • S’entén amb poc context? Si has de revisar 5 funcions abans de saber què fa una línia, alguna cosa està malament.

Tancament

Escriure bon codi no es tracta només de fer servir bé Python. Es tracta d’escriure una cosa que tu i d’altres podeu llegir, entendre i modificar sense por. Les eines ajuden, però no substitueixen el criteri. És millor escriure una mica més lent, amb intenció, que ràpid i enredat.

Aquestes primeres pràctiques són la base sobre la qual construir coses més complexes. Encara que semblin detalls menors, marquen la diferència entre scripts que sobreviuen i projectes que es tornen un problema.

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *