Delayed evaluation and setdefault()

anton muhin antonmuhin at rambler.ru
Mon Jan 19 13:39:40 EST 2004


Leo Breebaart wrote:

> Hi all,
> 
> I have a question about Python and delayed evaluation.
> 
> Short-circuiting of Boolean expressions implies that in:
> 
>    >>> if a() and b():
> 
> any possible side-effects the call to b() might have will not
> happen of a() returns true, because then b() will never be
> executed.
> 
> However, if I go looking for dictionary keys like this:
> 
>    >>> d = {}
>    >>> d.setdefault('foo', b())
> 
> then b() *does* get executed regardless of whether or not the
> value it returns is actually used ('foo' was not found) or not
> ('foo' was found). 
> 
> If b() has side-effects, this may not be what you want at all. It
> would seem to me not too exotic to expect Python to have some
> sort of construct or syntax for dealing with this, just as it
> supports Boolean short-circuiting.
> 
> So I guess my question is twofold: one, do people think
> differently, and if so why?; and two: is there any elegant (or
> other) way in which I can achieve the delayed evaluation I desire
> for setdefault, given a side-effect-having b()?
> 

It's normal---setdefault is just a method and its parameters get 
evaluted before the call occur. If you want this kind of lazy 
evaluation, I'd suggest something like this ('foo' in d) or 
(d.setdefault('foo', b()). If you want your value too, it gets even 
trickier.

Actually, if you really need this kind of functionality, it might be 
worth defining a function.

def lazysetdefault(d, key, func):
   if key not in d:
     d[key] = func()()
   return d[key]

lazysetdefault(d, 'foo', lambda: b())

However, are you real sure you need it?

regards,
anton.




More information about the Python-list mailing list