What is the best way to deal with multiple return types in Python's is_number? I have not tried decorators yet or functions within functions, but this current un-pythonic method seems a little convoluted. I don't like how I need to repeat myself when I check the return_type 3 times.

Any suggestions are welcome, especially if the repetion can be dealt with in an elegant way. Please note that I am not that interested in the numerous reference to test if an object is a number as I believe this part is incorporated within my solution. I am interested in addressing the 3x duplication to deal with the return type. Moreover, while I appreciate the locale method is the more rigorous way of dealing with internationalisation, I prefer the simplicity of allowing the caller more flexibility in choosing the characters. 

Also, some people on Stack Overflow just posted trivial solutions to the smaller boolean is_number function that has been asked many times.

def is_number(obj, thousand_sep=',', decimal_sep=None, return_type='b'):
    """ determines if obj is numeric.

    if return_type = b, returns a boolean True/False
    otherwise, it returns the numeric value

    Examples
    --------
    &gt;&gt;&gt; is_number(3)
    True
    &gt;&gt;&gt; is_number('-4.1728')
    True
    &gt;&gt;&gt; is_number('-4.1728', return_type='n')
    -4.1728
    &gt;&gt;&gt; is_number(-5.43)
    True
    &gt;&gt;&gt; is_number("20,000.43")
    True
    &gt;&gt;&gt; is_number("20.000,43", decimal_sep=",", thousand_sep=",")
    True
    &gt;&gt;&gt; is_number("20.000,43", decimal_sep=",", thousand_sep=".", return_type="n")
    20000.43
    &gt;&gt;&gt; is_number('Four')
    False
    &gt;&gt;&gt; is_number('Four', return_type='n')
    """
    try:
        if is_string(obj):
            if decimal_sep is None:
                value = float(obj.replace(thousand_sep, ""))
            else:
                value = float(obj.replace(thousand_sep, "").replace(decimal_sep, "."))
            if return_type.lower() == 'b':
                return True
            else:
                return value
        else:
            value = float(obj)
            if return_type.lower() == 'b':
                return True
            else:
                return value
    except ValueError:
        return False
        if return_type.lower() == 'b':
            return False
        else:
            return None
I am disregarding some questionable code (such as the fact that '3,,,4' would be handled identically to '34', and so forth), and as you mention, the fact that locale's atof is probably more fitting than write-your-own. I am doing so because, worse than those, I really don't like the return_type parameter and its usage.

I would strongly suggest separating this into two functions. For example a to_number which acts like return_type='n', or even throws an exception instead of returning None, and an is_number which calls to_number and converts the exception or None to False, and other values to True. Each function would have very simple usage thanks to very simple definitions, and their code would become simpler accordingly.