
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. -- Steve