Cómo lanzar excepciones con raise, capturarlas con try/except, usar else y finally, y definir excepciones personalizadas.
finally siempre se ejecuta, incluso si hay un return dentro del try. Si hay return en ambos, el return del finally sobreescribe al del try. Evita usar return dentro de finally.
# Patrón del curso: atributo de clase compartido entre instanciasfrom collections import defaultdict class DuplicateStudentError(Exception): duplicates = defaultdict(list) # atributo de CLASE, compartido def __init__(self, name, rut): super().__init__(f'Estudiante duplicado: {name} ({rut})') self.name = name self.rut = rut DuplicateStudentError.duplicates[rut].append(name) try: raise DuplicateStudentError('Ana', '12345678-9')except DuplicateStudentError as e: print(e) print(DuplicateStudentError.duplicates)