It seems to me this discussion is mixing some different issues.<div><br></div><div>(1) having secret parameters that don't show in help().</div><div><br></div><div>(2) injecting a value in some way</div><div><br></div>

<div>I think these should be thought about separately.</div><div><br></div><div><b>For secret parameters:</b> 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</div>

<div><br></div><div><font class="Apple-style-span" face="'courier new', monospace">  >>> <b><font class="Apple-style-span" color="#3333ff">@help.hide</font></b>("x,y")</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  def foo(a, b, x=[], y={}): pass</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">  </font></div><div><font class="Apple-style-span" face="'courier new', monospace">  >>> help(foo)</font></div><div><div><font class="Apple-style-span" face="'courier new', monospace">  Help on function foo in module __main__:</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">  </font></div><div><font class="Apple-style-span" face="'courier new', monospace">  f(a, b)</font></div><div><br></div></div><div><b>For injecting values:</b> There are several different cases. I'll use the arbitrary keyword <span class="Apple-style-span" style="font-family: 'courier new', monospace; "><b><font class="Apple-style-span" color="#3333ff">special</font></b></span> in the snippets below (but note that the keyword means something slightly different in each case):</div>

<div><br></div><div><font class="Apple-style-span" face="'courier new', monospace">  def foo1():</font></div><div><font class="Apple-style-span" face="'courier new', monospace">    x = </font><span class="Apple-style-span" style="font-family: 'courier new', monospace; "><b><font class="Apple-style-span" color="#3333ff">special </font></b></span><font class="Apple-style-span" face="'courier new', monospace">[]</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">    ...</font></div><div><font class="Apple-style-span" face="'courier new', monospace">    x.append(t)</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br>

</font></div><div>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.</div>

<div><br></div><div><font class="Apple-style-span" face="'courier new', monospace">  def foo2():</font></div><div><font class="Apple-style-span" face="'courier new', monospace">    <b><font class="Apple-style-span" color="#3333ff">special </font></b>y = 0</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">    ...</font></div><div><font class="Apple-style-span" face="'courier new', monospace">    y += t</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br>

</font></div><div>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:</div>

<div><br></div><div><div><font class="Apple-style-span" face="'courier new', monospace">  def foo1a():</font></div><div><font class="Apple-style-span" face="'courier new', monospace">    </font><span class="Apple-style-span" style="font-family: 'courier new', monospace; "><b><font class="Apple-style-span" color="#3333ff">special </font></b></span><font class="Apple-style-span" face="'courier new', monospace">_x = []</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">    x = </font><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">_x</span></div><div><font class="Apple-style-span" face="'courier new', monospace">    ... # might rebind x</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">    x.append(t)</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div></div><div>It's a bit clumsy to use the first case to handle the second case:</div>

<div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">  def foo2a():</span></div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">    y = </span><span class="Apple-style-span" style="font-family: 'courier new', monospace; "><b><font class="Apple-style-span" color="#3333ff">special </font></b></span><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">[0]</span></div>

<div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">    ...</span></div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">    y[0] += t</span></div>

<div><span class="Apple-style-span" style="font-family: 'courier new', monospace; "><br></span></div><div><div>In addition, there are other use cases being discussed. This creates a new scope for <font class="Apple-style-span" face="'courier new', monospace">i</font> every time through the loop:</div>

</div><div><br></div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">  def foo3():</span></div><div><font class="Apple-style-span" face="'courier new', monospace">    result = []</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">    for </font><span class="Apple-style-span" style="font-family: 'courier new', monospace; "><b><font class="Apple-style-span" color="#3333ff">special </font></b></span><font class="Apple-style-span" face="'courier new', monospace">i in range(10):</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">      def z(): return i</font></div><div><font class="Apple-style-span" face="'courier new', monospace">      result.append(z)</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div><div><div>And this injects a mock to replace a library function:</div></div><div><br></div><div><font class="Apple-style-span" face="'courier new', monospace">  def foo4():</font></div>

<div><font class="Apple-style-span" face="'courier new', monospace">    return random.random()</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  w = </font><span class="Apple-style-span" style="font-family: 'courier new', monospace; "><b><font class="Apple-style-span" color="#3333ff">special</font></b></span><font class="Apple-style-span" face="'courier new', monospace">(random.random=lambda: 0.1) foo4()</font></div>

<div><br></div><div>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.</div>

<div><br clear="all"><font face="arial, helvetica, sans-serif">--- Bruce</font><div><font face="arial, helvetica, sans-serif">Follow me: <a href="http://www.twitter.com/Vroo" target="_blank">http://www.twitter.com/Vroo</a> <a href="http://www.vroospeak.com" target="_blank">http://www.vroospeak.com</a></font></div>

<div><font face="arial, helvetica, sans-serif"><br></font></div><br><br></div>