From: Arnaud Delobelle on
Malte Helmert <helmert(a)> writes:

> Arnaud Delobelle wrote:
>> 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?
> I would say that it's not really the EAFP concept that is problematic
> here, but rather that the try block encompasses more code than it
> should. Generally try blocks should be as narrow as possible, i.e., they
> should contain only the part where you really want to catch a potential
> failure.
> "return val.latex()" does two separate things that might fail: the
> lookup of val.latex, and the actual method call. If I understood you
> correctly, you only want to catch the AttributeError in the "val.latex"
> lookup here, and hence I'd say the "correct" application of EAFP here
> would be something like:
> try:
> foo = val.latex
> except AttributeError:
> ...
> else:
> return foo()
> Whether that's any better than LBYL in this particular case is of course
> debatable -- one nice thing compared to your LBYL version is that it
> doesn't look up val.latex twice upon success. But you could also get
> that via the LBYLish:
> latex_method = getattr(val, "latex")
> if latex_method:
> return latex_method()

Ben, Malte,

Thanks for your informative replies. I can now see where my blind spot
was and that I never really used EAFP properly before. I think I will
go with one of the two solutions above (probably the second) as I feel
it's a bit heavy handed to create a closure and perhaps call it every
time the latex() function is called.


You are right. Believe me I am fully aware of this. To my shame I have
many thousands lines of Python without any tests in this project and I
don't even know where to start...

Thanks again,