Question

Say you have a function:

def divide(a, b):
    return a / b

This will obviously give a different result if a and b are float, int, or a combination. If you only care about the situation when a and b are floats, what is the best way to deal with this?

i)

def divide(a, b):
    if not isinstance(a, float):
        raise TypeError('a must be a float')
    if not isinstance(b, float):
        raise TypeError('b must be a float')
    return a / b

ii)

def divide(a, b):
    return float(a) / float(b)

iii) something else?

My preference is for ii), but a colleague argues that if you are using a and b elsewhere, then i) is more likely to prevent bugs.

This is obviously a somewhat trivial example, but my colleague has much more experience with C and I am struggling to explain why using isinstance doesn't really fit with duck-typing and that having it permeate through in our python code is not great.

Was it helpful?

Solution

Another option could be

def divide(a, b):
    return a * 1.0 / b

or

from __future__ import division

def divide(a, b):
    return a / b

OTHER TIPS

If you want to do true division, regardless of Python version and don't want to use future imports, then an alternative is:

from operator import truediv
print truediv(4, 2)
# 2.0

Which will always do true division and return a float regardless of its input (given an int/float)... Passing fractions/complex/decimals will have other output!

Why not using:

def divide(a, b):
    return float(a) / float(b)

Probably one conversion to float would also suffice.

I assume that divide() is just an example of a function that might silently produce a wrong result given arguments with unexpected types.

To avoid hardcoding the type check in the function, a generic function could be used e.g., get_items() function allows to treat both json object and json array uniformly (compare convert_decimal() implementations: the one with isinstance() calls vs. another with the generic get_items()).

If the dispatching based on only the type of the first argument is not enough; see Five-minute Multimethods in Python by by Guido van van Rossum.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top