Sentinel values for special cases

Ben Finney ben at benfinney.id.au
Thu Oct 26 21:17:46 EDT 2006


Howdy all,

Ned Batchelder blogged[0] about a debate over checking function
parameters, and to what extent dynamic typing should be relied upon.

I was one of many who commented, but I wrote what purports to be a
comprehensive checklist when considering special-case inputs for
functions. I thought the best way to puncture my ego would be to post
that list here and see how well it survives :-) Here goes:


If you have a special case, there are a few steps.

First, do you really need a special case, or are you just being
paranoid about type safety? Let the caller take care of whether they
mean what they say, and make your function do *one* job clearly and
simply. (This supports the 'insert_ids(get_global_ids())' idea
earlier.)

Second, do you *really* need a special case, or are you making your
function too complex? Be very suspicious of functions that are written
to do two different things depending on their input, and split them so
that both are simple and the caller can be explicit about what they
want. This doesn't preclude factoring out the code that's common to
both of them, of course.

Third, if you actually need a special case, can it be None? This is
the idiomatic Python "sentinel value", and it looks like the code
posted by 'sri' [reproduced below].

    def insert_ids(ids=None):
        if ids is None:
            ids = get_global_ids()

Note that if you're squeamish about using None,
but don't have a specific reason not to use it, use it; other
programmers will thank you for following convention.

Fourth, if you have decided that a magic sentinel value is called for
but None is already taken for some other purpose, don't use a
string. Use a unique do-nothing object, defined at the module level so
callers can easily get at it, like 'Dmitry Vasiliev' showed
[reproduced below].

    GLOBAL = object()

    def insert_ids(ids=GLOBAL):
        if ids is GLOBAL:
            ids = get_global_ids()

You won't accidentally use it, because it's defined only in one place
(you're comparing by 'is', remember) and it's not used for anything
except indicating the special case.

Fifth, there is no fifth. If you've come to the end and think it's too
complex, it probably is. Start at the top again.



[0]: <URL:http://www.nedbatchelder.com/blog/200610.html#e20061022T192641>

-- 
 \          "Immorality: The morality of those who are having a better |
  `\                                       time."  -- Henry L. Mencken |
_o__)                                                                  |
Ben Finney




More information about the Python-list mailing list