Why are functions atomic?

Alex Martelli aleax at mac.com
Fri May 4 22:54:47 EDT 2007


Michael <michael.forbes at gmail.com> wrote:

> Thus, whenever I need to pass information to a function, I use default
> arguments now.  Is there any reason not to do this other than the fact
> that it is a bit more typing?

You're giving your functions a signature that's different from the one
you expect it to be called with, and so making it impossible for the
Python runtime to diagnose certain errors on the caller's part.

For example, consider:

def makecounter_good():
    counts = {}
    def count(item):
        result = counts[item] = 1 + counts.get(item, 0)
        return result
    return count

c = makecounter_good()
for i in range(3): print c(23)

def makecounter_hmmm():
    counts = {}
    def count(item, counts=counts):
        result = counts[item] = 1 + counts.get(item, 0)
        return result
    return count

cc = makecounter_hmmm()
for i in range(3): print cc(23)

print cc(23, {})

print c(23, {})


Counters made by makecounter_good take exactly one argument, and
properly raise exceptions if incorrectly called with two; counters made
by makecounter_hmmm take two arguments (of which one is optional), and
thus hide some runtime call errors.

>From "import this":
"""
Errors should never pass silently.
Unless explicitly silenced.
"""

The miniscule "optimization" of giving a function an argument it's not
_meant_ to have somewhat breaks this part of the "Zen of Python", and
thus I consider it somewhat unclean.


Alex



More information about the Python-list mailing list