On Monday 23 November 2015 10:43, Gregory Ewing wrote: > Steven D'Aprano wrote: >> Memoisation isn't "esoteric", it is a simple, basic and widely-used >> technique used to improve performance of otherwise expensive functions. > > That may be true, but I don't think it's a good example > of a use for a shared, mutable default value, because > it's arguably an *abuse* of the default value mechanism. > > Whenever I want to cache function values, I use a module > level variable to hold the cache. It's clearer, and it > doesn't clutter the function signature with something > that isn't logically a part of it at all.
Neither solution is really fantastic, but they both get the job done. Module level global caches have all the disadvantages of global variables. You need a unique name for each function that uses one, it breaks encapsulation, and it leaves you at the mercy of any code which modifies the global. But I agree that having the cache in the function signature is a bit smelly. But smelly or not, it works well enough for a quick and dirty cache, and using the function parameter list to initialise static local variables is a moderately common thing to do. For example: help(random.randrange) Help on method randrange in module random: randrange(self, start, stop=None, step=1, int=<type 'int'>, default=None, maxwidth=9007199254740992L) method of random.Random instance Choose a random item from range(start, stop[, step]). I think it would be cleaner and better if Python had dedicated syntax for declaring static local variables: def randrange(self, start, stop=None, step=1): static int=type(1), default=None, maxwidth=9007199254740992L ... def func(a, b): static cache = {} ... Another good example of using a default mutable argument comes from Guido himself: https://www.python.org/doc/essays/graphs/ Note that the use of a mutable default is perfectly safe, because the default is never modified. -- Steve -- https://mail.python.org/mailman/listinfo/python-list