It seems to me this discussion is mixing some different issues.

(1) having secret parameters that don't show in help().

(2) injecting a value in some way

I think these should be thought about separately.

For secret parameters: help() could have a convention that it doesn't display variables with that start with _ or something like that, but that might have compatibility issues. Alternatively, there could be some new syntax or a decorator like

  >>> @help.hide("x,y")
  def foo(a, b, x=[], y={}): pass
  >>> help(foo)
  Help on function foo in module __main__:
  f(a, b)

For injecting values: There are several different cases. I'll use the arbitrary keyword special in the snippets below (but note that the keyword means something slightly different in each case):

  def foo1():
    x = special []

Sets x every time the function is called to the same static list. What's special here is that I have one list created that gets reused, not a new list every time. This is how default arguments work and is useful for an accumulating list.

  def foo2():
    special y = 0
    y += t

Initializes y once to 0 (at some time before the next line of code is reached). This is how static works in C++. This is what I want if my accumulating variable is a counter since numbers are immutable. This case easily handles the first case. If you never rebind x, you don't need to do anything special, otherwise something like this:

  def foo1a():
    special _x = []
    x = _x
    ... # might rebind x

It's a bit clumsy to use the first case to handle the second case:

  def foo2a():
    y = special [0]
    y[0] += t

In addition, there are other use cases being discussed. This creates a new scope for i every time through the loop:

  def foo3():
    result = []
    for special i in range(10):
      def z(): return i

And this injects a mock to replace a library function:

  def foo4():
    return random.random()
  w = special(random.random=lambda: 0.1) foo4()

Just because we might use similar hacks to do these now, doesn't mean that they are necessarily the same and I think the discussion has been going in several different directions simultaneously. I think all these cases have merits but I don't know which are more important. The last case seems to be handled reasonably well by various mock libraries using with, so I'm not particularly worried about it. I would like support for case 1 or 2. I don't like the idea of using a different function argument hack instead of the current one.

--- Bruce
Follow me: