Encapsulation, inheritance and polymorphism

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Jul 18 14:58:11 CEST 2012


On Tue, 17 Jul 2012 09:52:59 -0400, Roy Smith wrote:

> you could write in Python:
> 
> # Type matching will get checked at run-time 
> def my_function(mpf, ot):
>    assert isinstance(mpf, MassivelyParallelFrobinator) 
>    assert isinstance(ot, OtherThing)

Keep in mind that assertions are not guaranteed to run. Code like the 
above is buggy, because if Python is run under the -O (optimize) flag, 
assertions will be stripped out.

Assertions are mostly useful for two things:

1) "This cannot possibly happen, but just in case it does..."

If you've ever written something like this:

if x%2 == 0:
    do_spam()
elif x%2 == 1:
    do_ham()
else:
    # This can't happen!
    print("something unexpected happened")
    sys.exit()


that is better written as:

if x%2 == 0:
    do_spam()
else:
    assert x%2 == 1, "something unexpected happened"
    do_ham()


2) To check your internal reasoning in a function or method.

For example:

def foo(something):
    n = len(something)
    x = math.sqrt(x)
    # We expect that x must be less than half of n. 
    # E.g. n=100 gives 10 < 50, which is correct.
    assert x < n//2
    process(n, x)


Run with the -O flag, the (hopefully!) redundant test will be stripped 
out; without the flag, the test will check your logic for you and fail if 
the stated condition is not met.

For bonus points, can you see the mistake? The stated condition is wrong. 
Without the assert, the process() code could go off and potentially 
silently do the wrong thing, but the assert guards against that 
possibility. And once I've had a bug report that my app raises an 
AssertionError, I will go back and think more carefully about the 
assertion that sqrt(n) is always less than half of n.


> but that's just not the way people write code in Python.

Better is to use explicit type checks and raise an exception yourself:

    if not isinstance(x, int):
        raise TypeError('expected an int, got %r' % x)

Better still is to duck-type whenever you can.


-- 
Steven



More information about the Python-list mailing list