[Python-Dev] lazy evaluation redux (was dict "setdefault". Feaure request or bugfix?)

Rich Harkins rich@worldsinfinite.com
11 Feb 2003 10:45:06 -0500


On Tue, 2003-02-11 at 08:33, Alex Martelli wrote:
> On Tuesday 11 February 2003 01:23 pm, Jesus Cea Avion wrote:
> > <https://sourceforge.net/tracker/index.php?func=detail&aid=684542&group_id=
> >5470&atid=355470>
> >
> > Reading "python cookbook" I reach a very intelligent
> > dictionary construction: to use dictionary "setdefault"
> > to avoid a "get" or a "try...except".
> >
> > Nevertheless current "setdefault" behaviour is
> > questionable, since it evaluates the default value when
> > it is not necessary. In my mind, "setdefault" should
> > evaluate the default value when it need to use it, not
> > ALWAYS. Example:
> 

Slightly offtopic, but in the vein of setting default values in a
dictionary:

I, for one, would be more than happy if a __makeitem__ method existed
that would be called when:

1) __getitem__ would normally raise KeyError
2) get() is called without a default
3) setdefault is called without a default

__makeitem__ would then accept one parameter, the key name to make, and
return the object to return, as appropriate, through those functions. 
__makeitem__ could also modify the dictionary if caching of the result
is desired.  This is, IMHO, orthogonal to the __getattr__ method, except
it applies to keys, not attributes.

I think I would use this more than setdefault() since in many cases the
context for the defaulting exists in the dictionary-like object itself
and not in the calling context.  For example:

class Directory(dict):
	def __init__(self,path):
		self.path=path

	def __makeitem__(self,name):
		filepath=os.path.join(self.path,name)
		stats=os.stat(filepath)
		if stat.IS_DIR(stats[0]):
			return Directory(filepath)
		else:
			return File(filepath,stats)

	def keys(self):
		return os.path.listdir(self.path)

class File(object):
	def __init__(self,path,stats):
		self.path=path
		self.stats=stats

	def open(self):
		return open(self.path)

Using setdefault() without __makeitem__ I would have to do the following
to produce the same output, with bonus methods in my Dictionary:

dir.setdefault(name,dir.create(name))

ICK!  I'm having to reach into dir to perform a create (in other words
I'm going to create whether I like it or not).  This seems to me to be
less intuitive than:

dir[name]

Which, based on my abstraction, just does what it looks like it should
do - return the appropriate thing.

Rich