On Sat, Jun 11, 2011 at 9:30 AM, Jan Kaliszewski <zuo@chopin.edu.pl> wrote:

== Proposed solutions ==

I see three possibilities:

1.
To add a new keyword, e.g. `inject':
   def do_and_remember(val, verbose=False):
       inject mem = collections.Counter()
       ...
or maybe:
   def do_and_remember(val, verbose=False):
       inject collections.Counter() as mem
       ...

2. (which personally I would prefer)
To add `dummy' (or `hidden') keyword arguments, defined after **kwargs
(and after bare ** if kwargs are not needed; we have already have
keyword-only arguments after *args or bare *):

   def do_and_remember(val, verbose=False, **, mem=collections.Counter()):
       ...

do_and_remember(val, False, mem='something') would raise TypeError and
`mem' shoudn not appear in help() etc. as a function argument.

3.
To provide a special decorator, e.g. functools.within:
   @functools.within(mem=collections.Counter())
   def do_and_remember(val, verbose=False):
       ...

For these cases I use a class based solution. It's simple and easy to test. 


class DoAndRemember:

    def __init__(self):
        self._mem = collections.Counter()

    def __call__(self, val, verbose=False):
        result = do_something(val)
        self.mem[val] += 1
        if verbose:
            print('Done {} times for {!r}'.format(mem[val], val))

do_and_remember = DoAndRemember()


--
David
blog: http://www.traceback.org
twitter: http://twitter.com/dstanek
www: http://dstanek.com