[Python-ideas] proto-PEP: Fixing Non-constant Default Arguments

Roman Susi rnd at onego.ru
Wed Jan 31 09:24:04 CET 2007


Chris Rebert wrote:
> Roman Susi wrote:
> 
>> Chris Rebert wrote:
>>
>>> Jim Jewett wrote:
>>>
>>>> On 1/28/07, Chris Rebert <cvrebert at gmail.com> wrote:
>>
>>
>> /skip/
>>
>>>>>     def foo(bar=new baz):
>>>>>         #code
>>>>
>>>> This would be less bad.
>>>>
>>>> That said, I fear many new programmers would fail to understand when
>>>> they needed new and when they didn't, so that in practice, it would be
>>>> just optional random noise.
>>>
>>>
>>> This is part of the reason I'm trying to avoid adding new syntax.
>>> However, I assert that at least 'new' is clearer than the' x=None; if x 
>>
>>
>> But if you are concerned with the current None, there could be some
>> other, new False value serving the same need, like:
>>
>>     def foo(x, y, z, bar=Missing, qux=Missing):
>>         if baz is Missing:
>>             baz = []
>>         #code
>>
>> or even:
>>
>>     def foo(x, y, z, bar=, qux=):
>>         if baz is Missing:
>>             baz = []
>>         #code
>>
>> at least, it doesn't require decorators, is backward compatible
>> (hopefully no grammar conflicts in there), reads as English.
> 
> 
> Those examples are only slightly better than using None. The convention
> of using None to indicate use of a mutable/non-constant default value is
> about as clear as your examples.
> 
> The point wasn't that None wasn't descriptive/specific enough, but
> rather why have to write the 'bar=None' and then the 'if bar is None'
> when 'bar=[]' could be sufficient? Also, this indicates exactly what the
> default value is, as opposed to None/Missing, which is just an opaque
> indicator for 'some mutable/non-constant default value'.
> 
> Thus, I see no need for 'Missing' or a similar constant.

And I think it is overkill to add new syntax there. For example, if the
function or method is near the external (human or network) interface
border it is good to check ALL arguments anyway. So the extra

     if baz is Missing:
         baz = []

doesn't spoil the impression:

     def foo(x, y, z, baz=, qux=):
         ...
         if baz is Missing:
             baz = []

         ...
         if type(baz) != type([]) or len(baz) > 1000 or min(baz) < 0 or ...:
            raise ...

         #code


What I'd wanted to say is that =None or =Missing is not just
"indicator for 'some mutable/non-constant default value'." but
may also mean that the argument is subject to further constraints and
thus funtion code has checks for that.

So, instead of having clear indicator of missing argument we have some
fresh instance of a list or dict.

Also, in many situation another approach is used nowadays:

     def foo(x, y, z, **args):
        ...
        baz = args.get("baz", [])
        qux = args.get("qux", {})


Which has the effect proto-PEP author would like to achieve.
Of course, no automatic tools are going to make type checks with that
helpful function signature.

Also, while its offtopic in this post, I'd really liked Python 3000 to
have more unification for dict vs attribute access because there are use
cases (Storage in web.py, Namespace in mxTools - I am sure many other
projects have similar things) which single purpose is to have both dict
and attribute syntax in one data object interchangeably:

     def foo(**args):
        ...
        baz = args.baz
        qux = args["qux"]


Regards,
Roman

> 
> - Chris Rebert



More information about the Python-ideas mailing list