I'm often having code written as follows
try:
self.title = item.title().content.string
except AttributeError, e:
self.title = None
Is there a quicker way of dealing with this? a one-liner?
I'm often having code written as follows
try:
self.title = item.title().content.string
except AttributeError, e:
self.title = None
Is there a quicker way of dealing with this? a one-liner?
What exceptions are you getting from item.title()
? The bare except
(horrible practice!) doesn't tell us. If it's an AttributeError (where item
doesn't have a title
method, for example),
self.title = getattr(item, 'title', lambda: None)()
might be the one-liner you seek (but performance won't be enormously different, mind you;-).
Edit: as the OP entirely changed the question (it was originally just using self.title()
, it's now using self.title().content.string
, and does specifically catch AttributeError
rather than using a bare except
), the previous version of this answer of course doesn't apply any more. The proper answer now is: attempting a one-liner is an absurd approach, when the chain of attribute references &c keeps growing longer and longer (how many will there be next time, nine? Since they jumped from one to three with the first edit...;-).
And with no idea of which of the many elementary operations expressed by that long, Law of Demeter-scoffing chain of references might raise the AttributeError, any attempt at optimization would be flying rather blind, too.
You should know ahead of time whether or not an object has a given attribute. It is a bad sign when you have an object but do not know what it is.
You retrieve three attributes in your try block. A try block should contain as little code as possible. You could let an error pass silently if a different attribute is missing than you think.
getattr
lets you have a default value, but typically should not be used for this purpose.
In one line, although I’d only recommend this in 5% of all use cases.
self.title = item.title().content.string if hasattr(item, 'title') else None
Your question focuses on the speed of this operation. First, why do you think this operation is slow? Second, there isn't a faster way to access the attributes. Even trying to avoid the catch by checking for the attribute first will likely be slower, simply because of the Python conditionals needed to check if the attribute exists. Also, hasattr attempts to read the attribute, and catches AttributeError, returning False. So checking for the attribute will actually involve a try/except anyway.
How about a two-liner?
try: self.title = item.title().content.string
except AttributeError, e: self.title = None
Denser, less readable, but you really save two keypresses!
Assuming the AttributeError happens on string
:
self.title = getattr(item.title().content, 'string', None)