Hi all, Hi have a set of classes that represent mathematical objects which can be represented as a string using a 'latex' method (after Knuth's famous typesetting system). As I want to be able to typeset some builtin types as well, I have a generic function, latex(), as follows:
def latex(val): try: return val.latex() except AttributeError: if isinstance(val, (tuple, list)): return ", ".join(map(latex, val)) elif isinstance(val, dict): return ", ".join( "%s=%s" % (latex(k), latex(v)) for k, v in sorted(val.iteritems()) ) else: return str(val) It's EAFP and I have used this for a while with no problem. Recently I added a new class for 'n choose r' objects, as follows: class Choose(Expression): def __init__(self, n, r): self.subexprs = n, r self.n = n self.r = r def calc(self, ns=None, calc=calc): return choose(calc(self.n, ns), calc(self.r, ns)) def latex(self): return "{%s \\choose %s}" % (latex(self.n), latex(self.k)) When I create a Choose object and try to get its latex representation, this happens: >>> c = Choose(5, 3) >>> latex(c) '<qmm.maths.expressions.Choose object at 0x17c92d0>' This puzzled me for a bit: why is it not trying to use the latex() method of the Choose object? I read and reread the definition of the latex() method for a while until I found that there was a typo. Where it says: latex(self.k) it should say: latex(self.r) Thus it triggers an AttributeError, which is exactly the kind of exception that I am catching in the latex() function after trying val.latex(). (Of course I could have caught this by calling c.latex() directly but it's such a short method definition that I couldn't imagine missing the typo!). This means that EAFP made me hide a typo which would have been obviously detected had I LBYLed, i.e. instead of try: return val.latex() except AttributeError: ... do if hasattr(val, 'latex'): return val.latex() else: ... So was it wrong to say it's EAFP in this case? Should I have known to LBYL from the start? How do you decide which one to use? Up to now, I thought it was more or less a matter of taste but now this makes me think that at least LBYL is better than catching AttributeError. Thanks for any guidance. -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list