Arnaud Delobelle wrote:
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.
In addition to the other replies, you should've tested the Choose class. :-)
--
http://mail.python.org/mailman/listinfo/python-list