15.12.2022 Views

Python Eficaz

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

tipos. Por exemplo, podemos levantar uma exceção ValueError sempre que um

parâmetro inválido é passado para a função.

def determine_weight(volume, density):

if density <= 0:

raise ValueError('Density must be positive')

# ...

Em alguns casos, ValueError é o mais apropriado, mas para APIs (contrariando a

regra tácita citada) é muito mais vantajoso definir sua própria hierarquia de

exceções. Podemos fazê-lo definindo uma exceção-raiz chamada Exception no

módulo. Depois, todas as outras exceções levantadas por aquele módulo herdam

a exceção-raiz.

# my_module.py

class Error(Exception):

"""Base-class for all exceptions raised by this module."""

class InvalidDensityError(Error):

"""There was a problem with a provided density value."""

Ter uma exceção-raiz que é própria do módulo facilita a captura, pelos

consumidores da API, de todas as exceções que o módulo levanta

propositalmente. Por exemplo, o código a seguir mostra o consumidor de uma

API fazendo uma chamada a função em uma estrutura try/except que captura a

exceção-raiz do módulo:

try:

weight = my_module.determine_weight(1, -1)

except my_module.Error as e:

logging.error('Unexpected error: %s', e)

Esse try/except evita que as exceções da API se propaguem para os níveis

superiores na hierarquia de classes e, assim, acabem por causar um erro no

programa chamador. O try/except isola da API o código chamador, e esse

isolamento acarreta três efeitos muito úteis.

Primeiro, as exceções-raiz permitem que os chamadores entendam quando há

um problema em seu uso da API. Se os chamadores usam a API de forma

apropriada, eles devem ser capazes de capturar as várias exceções elevadas

www.full-ebook.com

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!