views:

140

answers:

3

I have a bunch of code that looks similar to this:

                try:
                    auth = page.ItemAttributes.Author
                except:
                        try:
                            auth = page.ItemAttributes.Creator
                        except:
                                auth = None

Is there a nicer way to write out this logic? This makes my code really painful to read. I thought try..finally would work, but I assumed wrong

+11  A: 

You can use hasattr to avoid the try/except blocks:

auth = None
for attrname in ['Author', 'Creator']:
    if hasattr(page.ItemAttributes, attrname):
        auth = getattr(page.ItemAttributes, attrname)
        break

An alternate way to write the above is to use the else clause of a Python for loop:

for attrname in ['Author', 'Creator']:
    if hasattr(page.ItemAttributes, attrname):
        auth = getattr(page.ItemAttributes, attrname)
        break
else:
    auth = None
Mark Byers
@Mark clean code
systempuntoout
+1 Not only is it cleaner but it eliminates the need to deal with exceptions completely.
BoltClock
@Mark a doubt.. how can you be sure that page has ItemAttributes?It could be None.
systempuntoout
Very cool. I wish I knew about this months ago when I was making huge exception chains. In this case it will always have ItemAttributes, interesting question though.
xporter
Very clean. Probably want to add `auth = None` before the for loop to directly match the OPs original solution and avoid a NameError if nothing ends up matching.
sdolan
@sdolan: +1 You're right. I've updated the answer.
Mark Byers
+3  A: 

This makes my code really painful to read

Whatever you do, don't catch wildcards. except: is the pythonic way to say: Hey, all exceptions are equal, I want every single error in my try block to end up here, I don't care if I catch an AttributeError or a WorldGotFuckedUpException. In your case, except AttributeError is much, much better AND easier to read.

This is just a side note. Mark's answer shows the best way to do it, IMHO.

Alexander Gessler
Haha, noted... I'm just lazy and probally need to have a really horrible experience before I will remember to catch specific exceptions.
xporter
+2  A: 

@Mark Byers's answer is more flexible, but if you wanted a one-liner

auth = getattr(page.ItemAttributes, 'Author', None) or getattr(page.ItemAttributes, 'Creator', None)
Joe Kington
This is not exactly the same -- `page.ItemAttributes.Author` could be `None`. The original code permits this case.
Alexander Gessler