What value should be passed to make a function use the default argument value?

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Sat Oct 7 03:25:03 CEST 2006

On Fri, 06 Oct 2006 12:42:08 +0200, Fredrik Lundh wrote:

> Antoon Pardon wrote:
>> IMO this is a very natural thought process for a python programmer.
>> So a python programmer seeing the first will tend to expect that
>> last call to work.
> on the other hand, if a Python programmer *writes* some code instead; 
> say, a trivial function like:
> 	def calculate(a, b):
>              # approximate; gonna have to fix this later
>              return a + b * 1.2
> chances are that he did *not* intend this to be called as
>          calculate(a=1, b=2)

Developers enable lots of things that they didn't intend. For example,
that function works perfectly well with complex numbers, regardless of
whether or not the developer who wrote it even knows that complex numbers

We've recently had rather vigorous argument on this list about an alleged
bug in cgi.escape, and the consensus was that it wasn't a bug, but *even
if it were* it couldn't be changed without making a backwards-incompatible
change, and therefore it wouldn't be changed.

For the developer to change the names of a and b in the above published
code would be a backwards-incompatible change.

Under the currently existing Python (rather than some future, hypothetical
Python, or some Python in an alternative reality) all Python arguments are
keyword arguments, whether the developer intends it or not. (Functions
written in C are different.)

At the very least, since names a and b are now part of his code's
published interface, he is responsible for documenting that they are
subject to change. The argument that we should assume that argument names
are subject to change unless told otherwise gets it backwards -- argument
names are part of the published interface to the code, just like the
function name, and therefore should NOT change without warning, if at all.

Now, since so many programmers seem to ignore best-practices, common
practices and even common sense, perhaps Fredrik's heuristic "don't assume
keyword args are keyword args unless explicitly told" might be good,
defensive programming -- a little like "just because the published
interface says the function returns an integer, don't assume it returns an
integer without checking" might be good, defensive practice too.

> or, for that matter,
>          calculate(b=2, a=1)
> or
>          calculate(1, b=2)
> just because the Python calling machinery currently happens to allow
> that.  And chances are that he did *not* expect to be stuck with those
> argument names for the foreseeable future, just because someone else
> decided to interpret things in the most literal way they possibly could.

There is a convention for marking names as "touch at your own risk". That
convention isn't "everything is touch at your own risk unless told
otherwise". The convention is to use names with a leading underscore.


More information about the Python-list mailing list