
On Tue, Oct 27, 2015 at 4:36 PM, Steven D'Aprano <steve@pearwood.info> wrote:
On Tue, Oct 27, 2015 at 04:30:41PM -0400, Yury Selivanov wrote:
On 2015-10-27 4:22 PM, Nikolaus Rath wrote:
Because it leaks into the enclosing scope.
Leaks what? Name? Name it _SENTINEL then.
It is still in the enclosing scope.
Bruce is right that what we really want is something like "static". Lacking that feature, one work-around is "make it a global variable, and give it a leading underscore", but that's just a work-around.
Consider:
_SENTINEL = object()
# Later: def spam(): ... def eggs(): ... def cheese(): ... def aardvark(): ...
As the module user, you can see the leading underscore in _SENTINEL and immediately forget all about it. But as the module maintainer, you cannot ignore _SENTINEL. Leading underscore or not, it is still part of the implementation, and maintenance is all about the implementation.
Which of the functions uses _SENTINEL? You can assume that *at least* one function uses it, but it may be more. Is it safe to rename it? Change it's value? To the maintainer, _SENTINEL is just another global variable, with all the disadvantages that has.
Better to put it inside the function, so the maintainer knows that it is local to the function:
def spam(): SENTINEL = object() ...
That's not bad, but what if the value is something harder to calculate?
def spam(): SENTINEL = next_prime_number(2**512) ...
At the moment, Python has an obvious way to calculate a value once only (make it a module-level global), and there is an obvious way to make a value local to a function (put it inside the function body). But there's no obvious way to do both together:
"Calculate this thing once only, AND make it local to this scope."
The unobvious and ugly way is to put the calculation in the function declaration as a default value:
def spam(SENTINEL=next_prime_number(2**512)): ...
which complicates the function signature and risks errors if the caller accidentally calls the function with too many arguments.
Python intentionally doesn't have this feature, and the argument you present sounds pretty weak (compared to the compelling argument *against* abusing the default argument syntax -- which also has a maintenance cost, as you have to explain it over and over). -- --Guido van Rossum (python.org/~guido)