Search code examples
pythoncastingcomparison

How does Python determine which type to cast something to?


Suppose I have the following:

x = "0"
y = 0
if x == y:
    print "You're winner!"

Will Python convert x to an int, or y to a string? Is there any way to control this behavior?


Solution

  • Python doesn't do any typecasting for you. If you want to control it, then you should be explicit.


    Note that just because python doesn't do any typecasting for you, various objects might. In this case, all of the magic is in the __eq__ method for int and str. When python sees:

    a == b
    

    It will try:

    a.__eq__(b)
    

    If that returns NotImplemented, it will then try b.__eq__(a). Otherwise, the return value of a.__eq__(b) will be returned and used as the result of the comparison. Obviously there are analogous "dunder" methods for other types of comparisons (__gt__, __lt__, __le__, etc).

    Very few builtin objects allow comparisons to different types -- in fact, the only builtin objects that I can think of off the top of my head that allow those sorts of shenanigans are int and float because most people expect 1.0 == 1 to be True...

    Also note that (for equality) most of the default comparisons return False if the types don't match. No error is raised. For other, more rich comparisons (e.g. __lt__, __gt__) the result is actually version dependent. Python2.x orders based on the type. It guarantees a consistent (but arbitrary) ordering.

    Python 2.7.10 (default, Oct 23 2015, 19:19:21) 
    [GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> '1' > 1
    True
    

    Python3.x does a smarter thing and disallows it completely by raising a TypeError:

    $ python3
    Python 3.5.1 (v3.5.1:37a07cee5969, Dec  5 2015, 21:12:44) 
    [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> '1' > 1
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unorderable types: str() > int()