[Python-ideas] Specifying constants for functions
Steven D'Aprano
steve at pearwood.info
Tue Oct 27 19:36:50 EDT 2015
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
More information about the Python-ideas
mailing list