[Python-ideas] Default arguments in Python - the return
Steven D'Aprano
steve at pearwood.info
Sat May 9 13:32:35 CEST 2009
On Sat, 9 May 2009 08:56:20 pm Pascal Chambon wrote:
> But what kills me with current default arguments is that those aren't
> even real static variables : they're "potentially static variables",
> and as far as I've seen, you have no easy way to check whether, for
> instance, the argument value that you've gotten is the default,
> static one, or a new one provided by the caller (of course, you can
> store the default value somewhere else for reference, but it's lamely
> redundant).
I'm not really sure why you would want to do that. The whole point of
default values is to avoid needing to care whether or not the caller
has provided an argument or not.
[...]
> Does it exist ? Do we have any way, from inside a call block, to
> browse the default arguments that this code block might receive ?
>>> def spam(n=42):
... return "spam "*n
...
>>> spam.func_defaults
(42,)
dir(func_object) is your friend :)
[...]
> but I agree that alternate syntaxes have led to infinite and complex
> discussions, and that the simpler solution I provided is likely to be
> too CPU intensive, more than I expected...
I would support... no, that's too strong. I wouldn't oppose the
suggestion that Python grow syntax for "evaluate this default argument
every time the function is called (unless the argument is given by the
caller)". The tricky part is coming up with good syntax and a practical
mechanism.
[...]
> On the other hand, would anyone support my alternative wish, of
> having a builtin "NotGiven", similar to "NotImplemented", and
> dedicated to this somehow usual taks of "placeholder" ?
There already is such a beast: None is designed to be used as a
placeholder for Not Given, Nothing, No Result, etc.
If None is not suitable, NotImplemented is also a perfectly good
built-in singleton object which can be used as a sentinel. It's already
used as a sentinel for a number of built-in functions and operators.
There's no reason you can't use it as well.
> There would be two major pros for this, imo :
> - giving programmers a handy object for all unvanted "mutable
> default argument" situations, without having to think "is None a
> value I might want to get ?"
But then they would need to think "Is NotGiven a value I might want to
get, so I can pass it on to another function unchanged?", and you would
then need to create another special value ReallyNotGiven. And so on.
> - *Important* : by appearing in the beginning of the doc near
> True and False, this keyword would be much more visible to beginners
> than the deep pages on "default argument handling" ; thus, they'd
> have much more chances to cross warnings on this Gotcha, than they
> currently have (and seeing "NotGiven" in tutorials would force them
> to wonder why it's so, it's imo much more explicit than seeing "None"
> values instead)
Heh heh heh, he thinks beginners read manuals :-)
> So, since reevaluation of arguments actually *is* a no-go, and
> forbidding mutable arguments is obviously a no-go too, would you
> people support this integrating of "NotGiven" (or any other name) in
> the builtins ? It'd sound to me like a good practice.
-1 on an extra builtin. There's already two obvious ones, and if for
some reason you need to accept None and NotImplemented as valid data,
then you can create an unlimited number of sentinels with object(). The
best advantage of using object() is that because the sentinel is unique
to your module, you can guarantee that nobody can accidentally pass it,
or expect to use it as valid data.
--
Steven D'Aprano
More information about the Python-ideas
mailing list