Reputation: 321
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
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
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