[TIP] Interesting getattr pattern [was: Re: [issue5728] Support telling TestResult objects a test run has finished]

Robert Collins robertc at robertcollins.net
Sat Apr 11 01:08:02 PDT 2009

On Sat, 2009-04-11 at 08:56 +0200, Raphael Marvie wrote:
> Hi,
> Interesting pattern mentioned (Michael tell me if I am wrong):
>  startTestRun = getattr(result, 'startTestRun', None)
>  if startTestRun is not None:
>      startTestRun()

Thats the pattern in my patch, yes. As its only done twice a test run,
in this case clarity really should win. So the performance aspect is
entirely notional :). But in an inner loop it matters a great deal
more :).

> My question is "what would be the increase in cost of doing an empty
> call compared to the if?" such as:
>  startTestRun = getattr(result, 'startTestRun', lambda: None)
>  startTestRun()
> If the lambda hurts you, one can define donothing() like:
>  def donothing():
>      pass

Either way you would be unconditionally constructing a callable
regardless of whether the attribute lookup succeeds, and thus would be
paying the cost of that. If you're in a loop where performance matters I
would expect the way I wrote it to be the cheapest unless you factor out
the lambda outside the loop (but keep it a local so you're not incurring
another lookup). That said, encountering such a performance critical
loop in a situation that wouldn't also call for a C extension is pretty
rare IME.


noop = lambda: None
for thing in things:
    getattr(thing, 'method', noop)()


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
Url : http://lists.idyll.org/pipermail/testing-in-python/attachments/20090411/ee70f9f4/attachment.pgp 

More information about the testing-in-python mailing list