Kuracha
Kuracha

Reputation: 321

Can I set exception for certain Attribute Error in Python?

I have short question, I'm courious and couldn't find any answer if I can set exception for certain AttributeError.

For example I have this error:

AttributeError: 'product.product' object has no attribute 'order_line'

And I want to set exception but only for this one AttributeError, so if another AttributeError would occur then I would see error message.

I tried doing this:

except AttributeError == 'product.product' object has no attribute 'order_line':
    break

But this isn't valid solution.

Upvotes: 2

Views: 3087

Answers (2)

bruno desthuilliers
bruno desthuilliers

Reputation: 77892

As a general rule, try blocks should be as short as possible to make sure you only catch the expected exception. IOW, instead of:

try:
   func_that_may_raise_attributeerror(obj)
   print(obj.attr_that_may_not_exist)
   other_function_that_may_also_raise_an_unrelated_attribute_error(obj)
   print(obj.another_attr_that_may_not_exist)
   and_yet_another_one(obj)
except AttributeError as e:
   # oops, who raised the exception and for which attribute ???

You should have something like:

try:
    val = obj.attr_that_may_not_exists
except AttributeError as e:
    # handle the case here
else:
    do_something_with_val(val)

Note that for function calls etc, you can add proper try/except blocks around the access to "attribute that may not exists" in the function itself and raise a custom exception (eventually with more context infos - ie the object and attribute - as exception arguments) instead of a generic AttributeError.

Now for your own use case, as mentionned by poke in a comment, the proper solution is to set product.product.order_line to None (or any other sentinel value) instead of deleting the attribute. While it is technically legal to dynamically add or delete attributes in Python, this should definitly not be done on attributes that are part of the class public interface - those attributes should always exists for the whole object's lifetime.

Upvotes: 2

Shashank V
Shashank V

Reputation: 11193

You can check if required message is in exception string.

except AttributeError as e:
    if "'product.product' object has no attribute 'order_line'" not in str(e):
        raise

But this is not recommended as you shouldn't be checking for attributes based of messages which can change in future.

Better approach would be to check if the attribute is present using hasattr

if hasattr(product.product, 'order_line'):
   # Do your stuff

Upvotes: 2

Related Questions