[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