As exceções são uma maneira poderosa e elegante de lidar com erros em seus programas Python. As exceções personalizadas levam esse poder a um novo nível.

As classes de exceção integradas do Python não abordam certas situações de erro que podem surgir no seu código. Nesses casos, você precisará criar exceções personalizadas para lidar com esses erros de maneira eficaz.

Em Python, você pode definir exceções personalizadas e acioná-las quando ocorrerem situações de erro específicas. Você pode gerenciar erros específicos e informativos com exceções personalizadas, melhorando a legibilidade e a capacidade de manutenção do seu código.

Por que você precisa de exceções personalizadas?

Durante o desenvolvimento de uma aplicação, vários cenários de erros podem surgir devido a alterações no código, integração com outros pacotes ou bibliotecas e interações com aplicações externas. É crucial lidar com esses erros para se recuperar deles ou lidar com falhas normalmente.

Python oferece uma variedade de exceção integrada

classes que cobrem erros como Erro de valor, Erro de tipo, Erro FileNotFound, e mais. Embora essas exceções integradas atendam bem ao seu propósito, elas só às vezes podem representar com precisão os erros que podem ocorrer em seu aplicativo.

Ao criar exceções personalizadas, você pode adaptá-las especificamente para atender aos requisitos do seu aplicativo e fornecer informações aos desenvolvedores que utilizam seu código.

Como definir exceções personalizadas

Para criar exceções personalizadas, definir uma classe Python que herda do Classe de exceção. O Exceção class oferece a funcionalidade básica necessária para lidar com exceções e você pode personalizá-la para adicionar recursos com base em suas necessidades específicas.

Ao criar classes de exceção personalizadas, mantenha-as simples e inclua atributos necessários para armazenar informações de erro. Os manipuladores de exceção podem então acessar esses atributos para tratar os erros de maneira adequada.

Aqui está uma classe de exceção personalizada, Meu erro personalizado:

classMyCustomError(Exception):
def__init__(self, message=None):
self.message = message
super().__init__(message)

Esta classe aceita um argumento de mensagem opcional durante a inicialização. Ele usa o super() método para chamar o construtor da base Exceção classe, que é essencial para o tratamento de exceções.

Como levantar exceções personalizadas

Para gerar um erro, use o elevação palavra-chave seguida por uma instância de sua classe de exceção personalizada, passando uma mensagem de erro como argumento:

ifTrue:
raise MyCustomError("A Custom Error Was Raised...")

Você também pode gerar o erro sem passar nenhum argumento:

ifTrue:
raise MyCustomError # shorthand

Qualquer formato é adequado para gerar erros personalizados.

Como lidar com exceções personalizadas

O tratamento de exceções personalizadas segue a mesma abordagem de lidar com exceções integradas. Usar tentar, exceto, e finalmente blocos para capturar exceções personalizadas e tomar as medidas apropriadas.

try:
print("Hello, You're learning how to MakeUseOf Custom Errors")
raise MyCustomError("Opps, Something Went Wrong...")
except MyCustomError as err:
print(f"Error: {err}")
finally:
print("Done Handling Custom Error")

Dessa forma, você pode lidar com todas as formas de exceções personalizadas levantadas.

Se ocorrer uma exceção durante a execução de um tentar bloco, um correspondente exceto bloco pode capturar e lidar com isso. Se não houver nenhum apropriado exceto bloco para tratar a exceção, qualquer finalmente O bloco será executado, seguido pela exceção sendo levantada novamente. Use um finalmente bloquear principalmente para executar tarefas de limpeza que devem ser executadas em qualquer circunstância, independentemente de ocorrer uma exceção ou não.

try:
raise KeyboardInterrupt
except MyCustomError as err:
print(f"Error: {err}")
finally:
print("Did not Handle the KeyboardInterrupt Error. \
Can Only Handle MyCustomError")

Nesta amostra, um TecladoInterrupção ocorre uma exceção, mas o exceto bloquear apenas alças Meu erro personalizado exceções. Neste caso, o finalmente o bloco é executado e a exceção não tratada surge novamente.

Herdando classes de erro personalizadas

Com base no conceito de programação orientada a objetos (OOP), você também pode herdar de classes de exceção personalizadas, assim como as classes regulares. Ao herdar de uma classe de exceção personalizada, você pode criar classes de erro que fornecem um contexto mais específico para uma exceção. Essa abordagem permite lidar com erros em diferentes níveis do seu código e fornece uma melhor compreensão do que causou o erro.

Digamos que você esteja desenvolvendo um aplicativo Web que interage com uma API externa. Esta API pode ter diferentes cenários de erro. Você desejará lidar com esses erros de forma consistente e clara em todo o seu código. Para conseguir isso, crie uma classe de exceção personalizada, BaseAPIException:

classBaseAPIException(Exception):
Base class for API-related exceptions.
def__init__(self, message):
super().__init__(message)
self.message = message

Depois de ter essa classe de exceção personalizada base, você pode criar classes de exceção filhas que herdam dela:

classAPINotFoundError(BaseAPIException):
Raised when the requested resource is not found in the API.
pass

classAPIAuthenticationError(BaseAPIException):
Raised when there's an issue with authentication to the API.
pass

classAPIRateLimitExceeded(BaseAPIException):
Raised when the rate limit for API requests is exceeded.
pass

Crie e capture essas exceções personalizadas ao fazer chamadas para a API em seu aplicativo Web. Trate-os adequadamente usando a lógica apropriada em seu código.

defrequest_api():
try:
# Simulate an API error for demonstration purposes
raise APINotFoundError("Requested resource not found.")
except APINotFoundError as err:
# Log or handle the 'Not Found' error case
print(f"API Not Found Error: {err}")
except APIAuthenticationError:
# Take appropriate actions for authentication error
print(f"API Authentication Error: {err}")
except APIRateLimitExceeded:
# Handle the rate limit exceeded scenario
print(f"API Rate Limit Exceeded: {err}")
except BaseAPIException:
# Handle other unknown API exceptions
print(f"Unknown API Exception: {err}")

A cláusula final except verifica a classe pai e atua como um pega-tudo para quaisquer outros erros relacionados à API.

Ao herdar classes de exceção personalizadas, você pode lidar com erros de maneira eficaz na API. Essa abordagem permite separar o tratamento de erros dos detalhes de implementação da API, tornando mais fácil adicionar exceções personalizadas ou fazer alterações conforme a API evolui ou encontra novos erros casos.

Envolvendo exceções personalizadas

Quebrar exceções significa capturar uma exceção, encapsulá-la em uma exceção personalizada e, em seguida, gerar essa exceção personalizada enquanto faz referência à exceção original como sua causa. Essa técnica ajuda a fornecer contexto para mensagens de erro e mantém os detalhes de implementação ocultos do código de chamada.

Considere o cenário em que seu aplicativo Web interage com uma API. Se a API gerar um Erro de pesquisa, você pode capturá-lo e criar um costume APINotFoundError exceção que faz referência ao LookupError como sua causa:

defrequest_api():
try:
# Simulate an API error for demonstration purposes
# Assuming the external API raised a LookupError
raise LookupError("Sorry, You Encountered A LookUpError !!!")
except LookupError as original_exception:
try:
# Wrap the original exception with a custom exception
raise APINotFoundError \
("Requested resource not found.") from original_exception
except APINotFoundError as wrapped_exception:
# Handle the wrapped exception here
print(f"Caught wrapped API exception: {wrapped_exception}")

# or re-raise it if necessary
raise

try:
request_api()
except APINotFoundError as err:
print(f"Caught API exception: {err.__cause__}")

Use um de cláusula com o elevação instrução para fazer referência à exceção original dentro de sua exceção personalizada.

Quando ocorre a exceção personalizada, ela inclui a exceção original como um __causa__ atributo, fornecendo um link entre a exceção personalizada e o original. Isso permite rastrear a origem de uma exceção.

Ao agrupar exceções, você pode fornecer um contexto mais significativo e enviar mensagens de erro mais apropriadas aos usuários, sem revelar detalhes internos de implementação do seu código ou da API. Também permite gerenciar e resolver tipos de erros de maneira estruturada e uniforme.

Personalizando o comportamento da classe em Python

Ao herdar a classe de exceção base fornecida pelo Python, você pode criar exceções simples e úteis que podem ser levantadas quando erros específicos ocorrem em seu código. Você também pode implementar um comportamento personalizado para suas classes de exceção com a ajuda de métodos magic ou dunder.