question of style

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Fri Jul 3 04:18:19 EDT 2009


On Thu, 02 Jul 2009 22:14:18 +0000, Tim Harig wrote:

> On 2009-07-02, Paul Rubin <http> wrote:
>> Tim Harig <usernet at ilthio.net> writes:
>>> If lower is 5 and higher is 3, then it returns 3 because 3 != None in
>>> the first if.
>> Sorry, the presumption was that lower <= higher, i.e. the comparison
>> had already been made and the invariant was enforced by the class
>> constructor.  The comment should have been more explicit, I guess.
> 
> That being the case, it might be a good idea either to handle the
> situation and raise an exception or add:
> 
> assert self.lower <= self.higher

Only if you want strange and mysterious bugs whenever somebody runs your 
code with the -O flag.

 
> That way an exception will be raised if there is an error somewhere else
> in the code rather then silently passing a possibly incorrect value.

asserts are disabled when the -O flag is given.

You should never use asserts for testing data. That's not what they're 
for. They're for testing program logic (and unit-testing).

This is wrong, because it will sometimes fail when running under -O:

def parrot(colour):
    assert colour.lower() in ('red', 'green', 'blue')
    return "Norwegian %s" % colour.title()

That should be written as test followed by an explicit raise:

def parrot(colour):
    if colour.lower() not in ('red', 'green', 'blue'):
        raise ValueError
    return "Norwegian %s" % colour.title()


An acceptable use for assert is to verify your program logic by testing 
something which should never fail. If it does fail, then you know 
something bizarre and unexpected has happened, and you have a program bug 
rather than bad data. Here's a silly example:


def cheese_available(kind):
    """Return True if the kind of cheese specified is in stock
    in the cheeseshop run by Michael Palin.

    This function always returns False.
    """
    return False


def get_cheese():
    exchange_amusing_banter()
    for kind in ('Cheddar', 'Gouda', 'Swiss', 'Camembert'):
        ask_proprietor("Do you have any %s?" % kind)
        flag = cheese_available(kind)
        assert not flag
        if flag:
            buy_cheese(kind)
            return None
        else:
            express_disappointment()
    # We only get here if no cheese is bought.
    print "Cleese: Does this cheeseshop actually have ANY cheese?"
    print "Palin: No sir, I'm afraid I've been wasting your time."
    print "Cleese: Well then, I'm going to have to shoot you."



-- 
Steven



More information about the Python-list mailing list